This is hopefully the results section for the Study 2 NSE & SE babies watching ASL Stories. We have two main factors:
- Language (Sign v. English)
- Direction (Forward v. Reversed)
Ages of babies are from 5 to 14.99 months. That means we lose two “old” CODA babies - Janine (16 mo) and za02 (23 mo). The dataset also contains factors for younger v. older babies IF we want to do age group splits. I do not recommend it because we lose all significance that way and we have more precise age information, better than brute groups. IF we do use it, the baby age groups are such:
- Younger babies = 5 to 8.99 months
- Older babies = 9.0 to 14.99 months
To skip to the XY Data, go here. To skip to the AOI/FCR analysis, go here.
Demographics
library(tidyverse)
library(janitor)
library(lme4)
library(lmerTest)
library(scales)
library(feather)
library(GGally)
# Grab data that was produced in 03importcleanbabies.Rmd
babies <- read_feather("cleanedbabyeyedata.feather") %>%
mutate(age = age*12) %>%
select(participant, language, age, gender, story, direction, mark, trial, repetition, aoi, secs, percent) %>%
rename(name = participant) %>%
mutate(agegroup = case_when(
age <= 8.99 ~ "younger",
age >= 9.0 & age < 15 ~ "older"
)) %>%
filter(!is.na(agegroup)) %>%
mutate(language = case_when(
language == "english" ~ "NSE",
language =="sign" ~ "SE"
)) %>%
rename(lang = language) %>%
mutate(lang2 = case_when(
name == "aubrey CODA 11m" ~ "HSE",
name == "GemmaF_11_4_13_CODA" ~ "HSE",
name == "Hannah_CODA_7m" ~ "HSE",
name == "ke11es12_7m_MomTerp" ~ "LSE",
name == "Miles_14m_SE" ~ "HSE",
name == "Parker 6 m SIGNING" ~ "HSE",
name == "Penn 6 months SIGN EXPOSED" ~ "HSE",
name == "Trinity 8m" ~ "LSE",
name == "Victoria07_18_17" ~ "LSE",
name == "Wells_8mos" ~ "LSE",
TRUE ~ lang
))
# filter(name != "Victoria07_18_17")
babiesinfo <- babies %>%
select(name, lang, age, gender) %>%
distinct() %>%
group_by(lang) %>%
summarise(N = n(),
age_mean = mean(age),
sd = sd(age),
min = min(age),
max = max(age))
genders <- babies %>%
select(name, lang, age, gender) %>%
distinct() %>%
group_by(lang, gender) %>%
summarise(N = n()) %>%
spread(gender, N)
babiesinfo <- left_join(babiesinfo, genders) %>%
select(lang, N, Female, Male, age_mean, sd, min, max) %>%
print()
babies$agegroup <- fct_relevel(babies$agegroup, c("younger","older"))
# IF we do age groups, use this code
#
# babiesinfo <- babies %>%
# select(name, lang, age, agegroup, gender) %>%
# distinct() %>%
# group_by(lang, agegroup) %>%
# summarise(N = n(),
# age_mean = mean(age),
# sd = sd(age),
# min = min(age),
# max = max(age))
#
# genders <- babies %>%
# select(name, lang, age, agegroup, gender) %>%
# distinct() %>%
# group_by(lang, agegroup, gender) %>%
# summarise(N = n()) %>%
# spread(gender, N)
#
# babiesinfo <- left_join(babiesinfo, genders) %>%
# select(lang, agegroup, N, Female, Male, age_mean, sd, min, max) %>%
# print()
Global Looking
We calculated percentages based on overall clip length as the denominator. In this way, we can meaningfully contrast looking times at the videos (which are variable lengths) based on different factors. But when we go to AOI analysis we need to re-calculate the percentages so the denominator is based on total looking time, not overall clip length.
The chart below shows little differences based on factors Age, Language, or Direction. That’s good, means the videos were equally engaging for all babies, right?
babies$lang <- as.factor(babies$lang)
babies_overall_looking <- babies %>%
group_by(name, age, lang, direction, story, repetition) %>%
summarise(percent = sum(percent)) # gets total looking percent for each trial for each baby
# Table of means
babies_overall_looking %>%
group_by(name, lang, direction) %>%
summarise(percent = mean(percent)) %>% # get average looking percent for each baby
group_by(lang, direction) %>%
summarise(mean_percent = mean(percent),
count = n(),
sd = sd(percent),
se = sd/sqrt(count)) %>%
select(-sd) %>%
print()
ggplot(babies_overall_looking, aes(x = age, y = percent, color = direction, fill = direction)) +
geom_jitter(alpha = 0.5) +
facet_grid(. ~ lang) +
geom_smooth(method = "lm", se = FALSE) +
ggtitle("Video Attention") +
xlab("age (months)") +
ylab("percent looking") +
theme_bw() +
scale_y_continuous(limits = c(0,1), labels = percent)

# Plot
# babies_overall_looking %>%
# group_by(lang, direction, name) %>%
# summarise(percent = mean(percent)) %>% # gets average looking percent for each baby
# group_by(lang, direction) %>%
# summarise(mean_percent = mean(percent), # gets group averages
# count = n(),
# sd = sd(percent),
# se = sd/sqrt(count)) %>%
# ggplot(aes(x = lang, y = mean_percent, fill = direction)) +
# geom_col(position = "dodge") +
# geom_errorbar(aes(ymin = mean_percent - se, ymax = mean_percent + se),
# position = position_dodge(width = 0.9), width = 0.25) +
# scale_y_continuous(limits = c(0,1), labels = percent) +
# theme_minimal() +
# theme(panel.grid.major.x = element_blank()) +
# # facet_wrap("lang") +
# ggtitle("Video Attention") +
# xlab("") +
# ylab("percent looking")
# babies_overall_looking %>%
# ggplot(aes(x = lang, y = percent, fill = direction)) +
# facet_wrap("agegroup") +
# geom_violin()
A linear model shows there were no significant effects of any factors. We can conclude there was no effect on how much the babies looked at the stimuli.
global_lm <- lmer(percent ~ age + lang * direction + (direction|name) + (direction|story), data = babies_overall_looking)
summary(global_lm)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: percent ~ age + lang * direction + (direction | name) + (direction | story)
Data: babies_overall_looking
REML criterion at convergence: -109.5
Scaled residuals:
Min 1Q Median 3Q Max
-2.17439 -0.71127 -0.01207 0.70541 2.47192
Random effects:
Groups Name Variance Std.Dev. Corr
name (Intercept) 0.0103084 0.10153
directionreversed 0.0009282 0.03047 1.00
story (Intercept) 0.0086180 0.09283
directionreversed 0.0039286 0.06268 -0.76
Residual 0.0330635 0.18183
Number of obs: 349, groups: name, 26; story, 8
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 0.679103 0.086923 28.572445 7.813 1.43e-08 ***
age 0.002021 0.008959 23.305300 0.226 0.824
langSE -0.049624 0.050507 23.785326 -0.983 0.336
directionreversed -0.033434 0.034821 12.347582 -0.960 0.355
langSE:directionreversed 0.019263 0.041732 94.210799 0.462 0.645
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) age langSE drctnr
age -0.854
langSE -0.051 -0.197
dirctnrvrsd -0.228 0.006 0.068
lngSE:drctn 0.034 -0.001 -0.126 -0.497
AOI Looking
Now we’ll re-calculate the percentages so the denominator is based on total looking time. All AOIs should sum up to 100% for each trial and each baby. Next let’s make a boxplot of all AOIs.
#Recalculate percent
babies <- babies %>%
select(-percent) %>%
group_by(name, lang, agegroup, age, direction, story, mark, trial, repetition, gender) %>%
mutate(totalsec = sum(secs)) %>%
group_by(name, lang, agegroup, age, direction, story, mark, trial, repetition, gender, aoi) %>%
mutate(percent = secs/totalsec)
# Boxplot
babies %>%
ggplot(aes(x = aoi, y = percent, fill = direction)) +
geom_boxplot() +
ggtitle("AOI Attention") +
theme_bw() +
xlab("") +
theme(axis.text.x = element_text(angle=45, hjust = 1),
panel.grid.major.x = element_blank()) +
scale_y_continuous(labels = scales::percent, limits = c(0,1))

It appears two important AOIs are MidChestTop and MidFaceBottom. Let’s look again only at midline AOIs:
midline = c("Belly","BelowChest","MidChestBottom","MidChestCenter","MidChestTop",
"MidFaceBottom","MidFaceCenter","MidFaceTop")
babies %>%
filter(aoi %in% midline) %>%
ggplot(aes(x = aoi, y = percent, fill = direction)) +
geom_boxplot() +
ggtitle("Midline AOI Attention") +
theme_bw() +
xlab("") +
theme(axis.text.x = element_text(angle=45, hjust = 1),
panel.grid.major.x = element_blank()) +
scale_y_continuous(labels = scales::percent, limits = c(0,1))

I’m going to run linear models with only MidChestTop or MidFaceBottom, and see what happens. No age interactions.
MidChestTop:
- Significant effect of age (p = 0.004) - older babies look at MidChestTop AOI more.
- Significant effect of language (p = 0.006) - NSE babies look +14.6% more than SE babies.
- Significant effect of direction (p = 0.046) - Babies look about 4.5% less for reversed
- No language X direction interaction.
MidFaceBottom:
- No effect of age
- Significant effect of language (p = 0.004) - SE babies look +21% more than NSE babies.
- Marginal effect of language (p = 0.073) - Babies look about 2% more for reversed.
- No language X direction interaction.
babies %>%
filter(aoi %in% c("MidFaceBottom","MidChestTop")) %>%
ggplot(aes(x = age, y = percent, color = direction, fill = direction)) +
geom_jitter(alpha = 0.5) +
geom_smooth(method = "lm", se = FALSE) +
scale_y_continuous(limits = c(0,1), labels = percent) +
theme_bw() +
# theme(panel.grid.major.x = element_blank()) +
facet_grid(aoi ~ lang) +
ggtitle("AOI Attention") +
xlab("") +
ylab("percent looking")

midchesttop_lm <- lmer(percent ~ age + lang * direction + (1|name) + (1|story), data = filter(babies, aoi == "MidChestTop"))
summary(midchesttop_lm)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: percent ~ age + lang * direction + (1 | name) + (1 | story)
Data: filter(babies, aoi == "MidChestTop")
REML criterion at convergence: -215.2
Scaled residuals:
Min 1Q Median 3Q Max
-3.0246 -0.7130 -0.1414 0.6022 2.6752
Random effects:
Groups Name Variance Std.Dev.
name (Intercept) 0.0114441 0.1070
story (Intercept) 0.0002891 0.0170
Residual 0.0253365 0.1592
Number of obs: 349, groups: name, 26; story, 8
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 0.110030 0.076921 23.643715 1.430 0.16568
age 0.029452 0.008477 22.192885 3.474 0.00213 **
langSE -0.134837 0.050436 27.916006 -2.673 0.01240 *
directionreversed -0.043631 0.022400 320.218547 -1.948 0.05232 .
langSE:directionreversed 0.038910 0.034773 317.931790 1.119 0.26400
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) age langSE drctnr
age -0.912
langSE -0.076 -0.188
dirctnrvrsd -0.137 -0.002 0.213
lngSE:drctn 0.084 0.006 -0.336 -0.645
#ggcoef(midchesttop_lm)
midfacebottom_lm <- lmer(percent ~ age + lang * direction + (1|name) + (1|story), data = filter(babies, aoi == "MidFaceBottom"))
summary(midfacebottom_lm)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: percent ~ age + lang * direction + (1 | name) + (1 | story)
Data: filter(babies, aoi == "MidFaceBottom")
REML criterion at convergence: -157.6
Scaled residuals:
Min 1Q Median 3Q Max
-2.42325 -0.77817 -0.02519 0.70580 2.50539
Random effects:
Groups Name Variance Std.Dev.
name (Intercept) 0.019877 0.14099
story (Intercept) 0.002498 0.04998
Residual 0.028516 0.16887
Number of obs: 349, groups: name, 26; story, 8
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 0.334139 0.099651 25.233307 3.353 0.00253 **
age -0.008939 0.010886 22.948912 -0.821 0.42004
langSE 0.193693 0.063648 26.900910 3.043 0.00518 **
directionreversed 0.038727 0.023881 317.208664 1.622 0.10587
langSE:directionreversed -0.052616 0.036996 315.990174 -1.422 0.15595
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) age langSE drctnr
age -0.903
langSE -0.065 -0.193
dirctnrvrsd -0.112 -0.002 0.179
lngSE:drctn 0.069 0.006 -0.283 -0.647
#ggcoef(midfacebottom_lm)
# Bar chart
# babies %>%
# filter(aoi %in% c("MidFaceBottom","MidChestTop")) %>%
# group_by(agegroup, lang, direction, name, aoi) %>%
# summarise(percent = mean(percent)) %>% # gets average looking percent for each baby
# group_by(agegroup, lang, direction, aoi) %>%
# summarise(mean_percent = mean(percent), # gets group averages
# count = n(),
# sd = sd(percent),
# se = sd/sqrt(count)) %>%
# ggplot(aes(x = lang, y = mean_percent, fill = direction)) +
# geom_col(position = "dodge") +
# geom_errorbar(aes(ymin = mean_percent - se, ymax = mean_percent + se),
# position = position_dodge(width = 0.9), width = 0.25) +
# scale_y_continuous(limits = c(0,1), labels = percent) +
# theme_minimal() +
# theme(panel.grid.major.x = element_blank()) +
# facet_grid(aoi ~ agegroup) +
# ggtitle("Video Attention") +
# xlab("") +
# ylab("percent looking")
Face-Chest Ratio
Next, we’ll define a Face-Chest Ratio (FCR) such that:
- MidFaceCenter, MidFaceBottom = Face
- MidChestTop, MidChestCenter, MidChestBottom, BelowChest = Chest
- FCR = face - chest / face + chest
We did not include Belly or MidFaceTop because of very low looking rates according to the boxplots above.
babies_fcr <- babies %>%
spread(aoi,percent) %>%
group_by(name, age, agegroup, lang, gender, direction, story, repetition) %>%
summarise(face = sum(MidFaceCenter, MidFaceBottom, na.rm = TRUE),
chest = sum(MidChestTop, MidChestCenter, MidChestBottom, BelowChest, na.rm = TRUE),
fcr = (face - chest) / (face + chest))
# Table of means
babies_fcr %>%
group_by(lang, direction, name) %>%
summarise(fcr = mean(fcr)) %>% # gets average looking percent for each baby
group_by(lang, direction) %>%
summarise(mean_fcr = mean(fcr), # gets group averages
count = n(),
sd = sd(fcr),
se = sd/sqrt(count)) %>%
select(-sd) %>%
print()
# Plot
ggplot(babies_fcr, aes(x = age, y = fcr, color = direction, fill = direction)) +
geom_jitter(alpha = 0.5) +
geom_smooth(method = "lm", se = FALSE) +
scale_y_continuous(limits = c(-1,1)) +
theme_bw() +
theme(panel.grid.major.x = element_blank()) +
facet_grid(. ~ lang) +
ggtitle("Face-Chest Ratios") +
xlab("") +
ylab("FCR")

# Bar chart
# babies_fcr %>%
# group_by(agegroup, lang, direction, name) %>%
# summarise(fcr = mean(fcr)) %>% # gets average looking percent for each baby
# group_by(agegroup, lang, direction) %>%
# summarise(mean_fcr = mean(fcr), # gets group averages
# count = n(),
# sd = sd(fcr),
# se = sd/sqrt(count)) %>%
# ggplot(aes(x = lang, y = mean_fcr, fill = direction)) +
# geom_col(position = "dodge") +
# geom_errorbar(aes(ymin = mean_fcr - se, ymax = mean_fcr + se),
# position = position_dodge(width = 0.9), width = 0.25) +
# scale_y_continuous(limits = c(-1,1)) +
# theme_minimal() +
# theme(panel.grid.major.x = element_blank()) +
# facet_wrap("agegroup") +
# ggtitle("Face-Chest Ratios") +
# xlab("") +
# ylab("FCR")
What will a linear mixed model tell us? (with no age interactions)
- No effect of age. Interesting. Maybe because we don’t have that many babies.
- Strong effect of language: SE babies have overall +0.50 FCR than NSE babies (p = 0.008); in other words, they are more attracted to the face.
- Effect of direction: Reversal increases FCR by +0.12 across all babies (p = 0.032). Interesting.
- Weak language x direction interaction. It seems NSE babies have a bigger reversal effect than SE babies? Trying to judge from the heat maps. (p = 0.095). BUt it’s so weak so possibly not worth mentioning.
fcr_lm <- lmer(fcr ~ age + lang * direction + (1|name) + (1|story), data = babies_fcr)
summary(fcr_lm)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: fcr ~ age + lang * direction + (1 | name) + (1 | story)
Data: babies_fcr
REML criterion at convergence: 435.5
Scaled residuals:
Min 1Q Median 3Q Max
-2.2135 -0.7622 0.1098 0.6343 2.3489
Random effects:
Groups Name Variance Std.Dev.
name (Intercept) 0.14776 0.3844
story (Intercept) 0.01342 0.1158
Residual 0.15708 0.3963
Number of obs: 349, groups: name, 26; story, 8
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 0.07490 0.26654 24.59417 0.281 0.7811
age -0.04443 0.02930 22.87598 -1.516 0.1431
langSE 0.45427 0.16972 25.84156 2.677 0.0127 *
directionreversed 0.11887 0.05605 316.96084 2.121 0.0347 *
langSE:directionreversed -0.14367 0.08683 315.78391 -1.655 0.0990 .
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) age langSE drctnr
age -0.908
langSE -0.060 -0.196
dirctnrvrsd -0.098 -0.002 0.158
lngSE:drctn 0.060 0.005 -0.249 -0.647
Heat Maps
And now heat maps!
heatmap_babies <- babies %>%
filter(aoi %in% midline) %>%
ungroup() %>%
group_by(lang, name, direction, aoi) %>%
summarise(percent = mean(percent, na.rm=TRUE)) %>%
group_by(lang, direction, aoi) %>%
summarise(percent = mean(percent, na.rm=TRUE)) %>%
ungroup() %>%
mutate(aoi = factor(aoi, levels = c("Belly","BelowChest","MidChestBottom","MidChestCenter","MidChestTop",
"MidFaceBottom","MidFaceCenter","MidFaceTop")))
ggplot(heatmap_babies, aes(x = lang, y = aoi)) +
geom_tile(aes(fill=percent),color="lightgray",na.rm=TRUE) +
# scale_fill_viridis(option = "viridis", direction=-1, limits = c(0,.7), labels = percent, name = "looking time") +
scale_fill_gradient(low = "#ffffff", high = "#08519c", space = "Lab", limits = c(0,.451), labels = percent, name = "looking time", na.value = "grey50") +
theme_bw() +
theme(strip.text.x = element_text(size = 11, color = "black", face = "italic"),
strip.background = element_rect(colour = "white", fill = "white"),
panel.grid.major = element_line(color = "white")) +
facet_grid(. ~ direction) +
ylab("") + xlab("") + ggtitle("Eye Gaze Heat Map, by Direction") +
scale_y_discrete(expand=c(0,0)) +
scale_x_discrete(expand = c(0,0))

ggplot(heatmap_babies, aes(x = direction, y = aoi)) +
geom_tile(aes(fill=percent),color="lightgray",na.rm=TRUE) +
# scale_fill_viridis(option = "viridis", direction=-1, limits = c(0,.7), labels = percent, name = "looking time") +
scale_fill_gradient(low = "#ffffff", high = "#08519c", space = "Lab", limits = c(0,.451), labels = percent, name = "looking time", na.value = "grey50") +
theme_bw() +
theme(strip.text.x = element_text(size = 11, color = "black", face = "italic"),
strip.background = element_rect(colour = "white", fill = "white"),
panel.grid.major = element_line(color = "white")) +
facet_grid(. ~ lang) +
ylab("") + xlab("") + ggtitle("Eye Gaze Heat Map, by Language") +
scale_y_discrete(expand=c(0,0)) +
scale_x_discrete(expand = c(0,0))

Different Ways to Visualize Reversal
I want to try to visualize reversal effects a different way. Maybe this.
# Get participant-level data
babies_fcr2 <- babies_fcr %>%
group_by(name, age, lang, direction) %>%
summarise(fcr = mean(fcr))
# reversal_effect_lm <- lmer(fcr ~ age + lang * direction + (1|name), data = babies_fcr2)
# summary(reversal_effect_lm)
ggplot(babies_fcr2, aes(x = direction, y = fcr, color = lang, fill = lang)) +
geom_point() +
geom_line(aes(group = name)) +
facet_grid(. ~ lang) +
scale_y_continuous(limits = c(-1,1)) +
theme_bw()

Or a reversal effect chart? Okay, so this chart tells us overall there really wasn’t much of a reversal effect for SE babies, they’re all hovering around 0. Interesting. While there seems to be a reversal effect for NSE babies where they look at the face more during reversed stories!
# Get participant-level data
babies_fcr3 <- babies_fcr2 %>%
spread(direction, fcr) %>%
group_by(name, age, lang) %>%
summarise(diff = forward - reversed)
ggplot(babies_fcr3, aes(x = age, y = diff, color = lang)) +
geom_point() +
geom_smooth(method = "lm", se = FALSE) +
scale_y_continuous(limits = c(-1,1)) +
theme_bw() +
ggtitle("Reversal Effect") +
ylab("Forward FCR - Reversed FCR")

This analysis of within-subject variation here:
# First get the mean of each trial, THEN the participant-level means
within_subjects <- babies_fcr %>%
group_by(name, lang, direction, story, repetition) %>%
summarise(fcr = mean(fcr, na.rm = TRUE),
count = n()) %>%
group_by(name, lang, direction) %>%
summarise(mean = mean(fcr, na.rm = TRUE),
se = sd(fcr, na.rm = TRUE)/sqrt(n()),
count = n())
# Then spread out mean and SE columns by direction
within_subjects_means <- within_subjects %>%
select(-se, -count) %>%
spread(direction, mean, sep = "_")
within_subjects_se <- within_subjects %>%
select(-mean, -count) %>%
spread(direction, se, sep = "SE")
within_subjects <- left_join(within_subjects_means, within_subjects_se, by = c("name","lang"))
# Now let's plot
lims <- c(-1,1)
within_subjects %>%
ggplot(aes(x = direction_forward, y = direction_reversed, color = lang)) +
geom_abline() +
geom_point(size = 2) +
geom_errorbar(aes(ymin=direction_reversed-directionSEreversed, ymax=direction_reversed+directionSEreversed)) +
geom_errorbarh(aes(xmin=direction_forward-directionSEforward, xmax=direction_forward+directionSEforward)) +
theme_bw() +
theme(aspect.ratio = 1) +
scale_x_continuous("forward", limits = c(-1,1)) +
scale_y_continuous("reversed", limits = c(-1,1)) +
ggtitle("FCR Means") +
facet_wrap("lang")

And a classic box/error plot with age collapsed.
babies_fcr2 %>%
group_by(lang, direction) %>%
summarise(fcr_mean = mean(fcr),
sd = sd(fcr),
n = n(),
se = sd/sqrt(n)) %>%
ggplot(aes(x = lang, y = fcr_mean, fill = direction)) +
geom_bar(stat = "identity", position = position_dodge()) +
geom_errorbar(aes(ymin = fcr_mean-se, ymax = fcr_mean+se), position = position_dodge(0.9), width = 0.2) +
scale_y_continuous(limits = c(-0.5, 0.5)) +
theme_linedraw()

Discussion re AOI/anatomical data
The biggest change is we lost the interaction between language and direction. For the ICSLA abstract we reported a strong interaction (p = 0.01), but now it’s p = 0.10. Shoot.
The interpretation here is that:
- All babies looked equally at all videos regardless of language or direction. Good!
- SE babies are stronger face-lookers than NSE babies. (Same as ICSLA)
- Reversal appears to affect NSE babies more than SE babies? (Marginal). This is unlike ICSLA.
XY Space Data
We’ll load the data from the childxydata.feather file made in 06rawxydata.Rmd. So any new babies, please run the first code block in 06 to include it. Then we’ll keep all the babies we also have in the AOI data group.
included <- babies %>%
ungroup() %>%
select(name) %>%
distinct() %>%
unlist()
xydata <- read_feather("../Child Data/childxydata.feather") %>%
rename(name = participant) %>%
filter(name %in% included)
# Get ages
ages <- read_csv("childrenages.csv") %>%
rename(name = participant)
xydata <- xydata %>% left_join(ages, by = "name") %>%
mutate(age = age*12) %>%
mutate(agegroup = case_when(
age <= 8.99 ~ "younger",
age >= 9.0 & age < 15 ~ "older"
)) %>%
mutate(language = case_when(
language == "EnglishExposed" ~ "NSE",
language == "SignLanguageExposed" ~ "SE"
)) %>%
rename(lang = language) %>%
select(name, group, gender, lang, condition, mark, trial, repetition, x, y, age, agegroup) %>%
separate(condition, into = c("story", "clip", "direction")) %>%
unite("story", c("story", "clip")) %>%
mutate(direction = case_when(
direction == "ER" ~ "reversed",
direction == "FW" ~ "forward"
)) %>%
mutate(name = factor(name),
group = factor(group),
gender = factor(gender),
lang = factor(lang),
story = factor(story),
direction = factor(direction),
mark = factor(mark),
trial = factor(trial),
repetition = factor(repetition),
agegroup = factor(agegroup))
Overall Looking
Let’s check that we have no significant group or condition differences in terms of valid (not empty) data points collected. This is same as “Global Looking” we have above, really, but w raw xy data.
xy_overall <- xydata %>%
filter(!is.na(x)) %>%
group_by(name, age, lang, direction, story, repetition) %>%
summarise(data_points = n()) # gets total looking percent for each trial for each baby
# Table of means
xy_overall %>%
group_by(name, lang, direction) %>%
summarise(data_points = mean(data_points)) %>% # get average looking percent for each baby
group_by(lang, direction) %>%
summarise(mean_data_points = mean(data_points),
count = n(),
sd = sd(data_points),
se = sd/sqrt(count)) %>%
select(-sd) %>%
print()
ggplot(xy_overall, aes(x = age, y = data_points, color = direction, fill = direction)) +
geom_jitter(alpha = 0.5) +
facet_grid(. ~ lang) +
geom_smooth(method = "lm", se = FALSE) +
ggtitle("Data Points") +
xlab("age (months)") +
ylab("data points recorded") +
theme_bw()

A linear model shows there were no significant effects of any factors. We can conclude there was no effect on how much data was collected from the babies.
overall_xy_lm <- lmer(data_points ~ age + lang * direction + (direction|name) + (direction|story), data = xy_overall)
summary(overall_xy_lm)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: data_points ~ age + lang * direction + (direction | name) + (direction | story)
Data: xy_overall
REML criterion at convergence: 5528.3
Scaled residuals:
Min 1Q Median 3Q Max
-3.7588 -0.6663 -0.0078 0.6278 2.5542
Random effects:
Groups Name Variance Std.Dev. Corr
name (Intercept) 20748.3 144.04
directionreversed 827.6 28.77 1.00
story (Intercept) 22549.1 150.16
directionreversed 4215.1 64.92 -0.05
Residual 52385.3 228.88
Number of obs: 401, groups: name, 26; story, 8
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 524.548 120.054 29.519 4.369 0.000141 ***
age 8.531 12.060 23.322 0.707 0.486339
langSE 8.304 68.321 23.886 0.122 0.904275
directionreversed -20.437 38.068 11.693 -0.537 0.601428
langSE:directionreversed -16.638 48.592 131.756 -0.342 0.732595
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) age langSE drctnr
age -0.828
langSE -0.040 -0.204
dirctnrvrsd -0.045 -0.003 0.063
lngSE:drctn 0.026 0.002 -0.130 -0.499
XY Data LMMs
Now we’re going to run LMMs on babies’ raw:
- horizontal spread (middle 50% of x data; xIQR)
- vertical spread (middle 50% of y data; yIQR)
- viewing area (A = middle-x * middle-y; area)
But to do this we first trim each baby’s data, getting rid of the first 60 samples (0.5 secs) of each trial.
xydata <- xydata %>%
group_by(name,trial) %>%
slice(60:n())
iqr <- xydata %>%
group_by(name, age, lang, story, direction, trial) %>%
summarise(xIQR = IQR(x,na.rm=TRUE),
yIQR = IQR(y,na.rm=TRUE),
xmed = median(x, na.rm=TRUE),
ymed = median(y, na.rm=TRUE),
area = xIQR*yIQR)
head(iqr,20)
Middle X
Results tell us that there is a significant effect of age where horizontal spread grew narrower with older babies (p = 0.024; slope = -2.2 px/month). There was a marginal effect of language where SE babies have slightly narrower horizontal spread (11 px; p = 0.088). No effects of reversal or interactions.
xiqr_mean <- iqr %>%
group_by(lang, direction, name) %>%
summarise(xIQR = mean(xIQR, na.rm = T)) %>% # gets average looking percent for each baby
group_by(lang, direction) %>%
summarise(mean_xIQR = mean(xIQR), # gets group averages
count = n(),
sd = sd(xIQR),
se = sd/sqrt(count)) %>%
select(-sd) %>%
print()
# Plot
ggplot(iqr, aes(x = age, y = xIQR, color = direction, fill = direction)) +
geom_jitter(alpha = 0.5) +
geom_smooth(method = "lm", se = FALSE) +
theme_bw() +
theme(panel.grid.major.x = element_blank()) +
facet_grid(. ~ lang) +
ggtitle("Horizontal Spread") +
xlab("") +
ylab("xIQR")

ggplot(xiqr_mean, aes(x = lang, y = mean_xIQR, fill = direction)) +
geom_bar(stat = "identity", position = position_dodge()) +
geom_errorbar(aes(ymin = mean_xIQR-se, ymax = mean_xIQR+se), position = position_dodge(0.9), width = 0.2) +
theme_linedraw()

xiqr_lm <- lmer(xIQR ~ age + lang * direction + (1|name) + (1|story), data = iqr)
summary(xiqr_lm)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: xIQR ~ age + lang * direction + (1 | name) + (1 | story)
Data: iqr
REML criterion at convergence: 3839.2
Scaled residuals:
Min 1Q Median 3Q Max
-2.1407 -0.4782 -0.1683 0.2668 9.8629
Random effects:
Groups Name Variance Std.Dev.
name (Intercept) 104.0925 10.2026
story (Intercept) 0.4767 0.6905
Residual 901.8472 30.0308
Number of obs: 398, groups: name, 26; story, 8
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 63.5887 8.5596 25.6516 7.429 7.5e-08 ***
age -2.2423 0.9342 23.2148 -2.400 0.0248 *
langSE -12.0971 6.0828 41.5383 -1.989 0.0533 .
directionreversed 1.9022 3.8627 372.0710 0.492 0.6227
langSE:directionreversed 0.1790 6.1817 369.3456 0.029 0.9769
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) age langSE drctnr
age -0.901
langSE -0.106 -0.175
dirctnrvrsd -0.213 -0.006 0.308
lngSE:drctn 0.135 0.002 -0.504 -0.625
Middle Y
We had a significant effect of age where vertical spread got narrower with older babies (p = 0.019, slope = -5.5 px/month). There were no effect of language, direction, or interactions.
yiqr_mean <- iqr %>%
group_by(lang, direction, name) %>%
summarise(yIQR = mean(yIQR, na.rm = T)) %>% # gets average looking percent for each baby
group_by(lang, direction) %>%
summarise(mean_yIQR = mean(yIQR), # gets group averages
count = n(),
sd = sd(yIQR),
se = sd/sqrt(count)) %>%
select(-sd) %>%
print()
# Plot
ggplot(iqr, aes(x = age, y = yIQR, color = direction, fill = direction)) +
geom_jitter(alpha = 0.5) +
geom_smooth(method = "lm", se = FALSE) +
theme_bw() +
theme(panel.grid.major.x = element_blank()) +
facet_grid(. ~ lang) +
ggtitle("Vertical Spread") +
xlab("") +
ylab("yIQR")

ggplot(yiqr_mean, aes(x = lang, y = mean_yIQR, fill = direction)) +
geom_bar(stat = "identity", position = position_dodge()) +
geom_errorbar(aes(ymin = mean_yIQR-se, ymax = mean_yIQR+se), position = position_dodge(0.9), width = 0.2) +
theme_linedraw()

yiqr_lm <- lmer(yIQR ~ age + lang * direction + (1|name) + (1|story), data = iqr)
summary(yiqr_lm)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: yIQR ~ age + lang * direction + (1 | name) + (1 | story)
Data: iqr
REML criterion at convergence: 4251.3
Scaled residuals:
Min 1Q Median 3Q Max
-2.7516 -0.5310 -0.2210 0.3696 5.8948
Random effects:
Groups Name Variance Std.Dev.
name (Intercept) 6.890e+02 2.625e+01
story (Intercept) 7.045e-12 2.654e-06
Residual 2.480e+03 4.979e+01
Number of obs: 398, groups: name, 26; story, 8
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 119.653 19.332 24.309 6.189 2.03e-06 ***
age -5.506 2.136 23.024 -2.578 0.0168 *
langSE -16.804 13.040 32.003 -1.289 0.2068
directionreversed 8.778 6.407 371.087 1.370 0.1715
langSE:directionreversed -5.713 10.252 370.630 -0.557 0.5777
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) age langSE drctnr
age -0.912
langSE -0.079 -0.187
dirctnrvrsd -0.156 -0.005 0.238
lngSE:drctn 0.099 0.001 -0.390 -0.625
Viewing Area
Again, age is significant (p = 0.01) such that area gets smaller with age (about 500 sq. px. per month). No effect of language or direction or interactions.
area_mean <- iqr %>%
group_by(lang, direction, name) %>%
summarise(area = mean(area, na.rm = T)) %>% # gets average looking percent for each baby
group_by(lang, direction) %>%
summarise(area_mean = mean(area), # gets group averages
count = n(),
sd = sd(area),
se = sd/sqrt(count)) %>%
select(-sd) %>%
print()
# Plot
ggplot(iqr, aes(x = age, y = area, color = direction, fill = direction)) +
geom_jitter(alpha = 0.5) +
geom_smooth(method = "lm", se = FALSE) +
theme_bw() +
theme(panel.grid.major.x = element_blank()) +
facet_grid(. ~ lang) +
ggtitle("Viewing Area") +
xlab("") +
ylab("Area (px^2)")

ggplot(area_mean, aes(x = lang, y = area_mean, fill = direction)) +
geom_bar(stat = "identity", position = position_dodge()) +
geom_errorbar(aes(ymin = area_mean-se, ymax = area_mean+se), position = position_dodge(0.9), width = 0.2) +
theme_linedraw()

area_lm <- lmer(area ~ age + lang * direction + (1|name) + (1|story), data = iqr)
summary(area_lm)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: area ~ age + lang * direction + (1 | name) + (1 | story)
Data: iqr
REML criterion at convergence: 8154.5
Scaled residuals:
Min 1Q Median 3Q Max
-1.6788 -0.2727 -0.1278 0.0299 13.4544
Random effects:
Groups Name Variance Std.Dev.
name (Intercept) 6.231e+06 2.496e+03
story (Intercept) 4.677e-10 2.163e-05
Residual 5.292e+07 7.275e+03
Number of obs: 398, groups: name, 26; story, 8
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 9372.80 2085.26 25.71 4.495 0.00013 ***
age -589.26 227.76 23.24 -2.587 0.01640 *
langSE -2048.69 1480.52 41.32 -1.384 0.17386
directionreversed 712.93 935.49 372.10 0.762 0.44648
langSE:directionreversed -303.67 1497.33 371.32 -0.203 0.83940
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) age langSE drctnr
age -0.902
langSE -0.105 -0.176
dirctnrvrsd -0.211 -0.006 0.307
lngSE:drctn 0.134 0.002 -0.502 -0.625
Plotting Viewing Area
medians <- iqr %>%
group_by(name,lang,direction) %>%
summarise(xIQR = median(xIQR,na.rm=TRUE),
yIQR = median(yIQR,na.rm=TRUE),
xmed = median(xmed,na.rm=TRUE),
ymed = median(ymed,na.rm=TRUE)) %>%
group_by(lang,direction) %>%
summarise(xIQR = mean(xIQR,na.rm=TRUE),
yIQR = mean(yIQR,na.rm=TRUE),
x = median(xmed,na.rm=TRUE),
y = median(ymed,na.rm=TRUE)) %>%
mutate(y = y*-1,
xmin = x-(xIQR/2),
xmax = x+(xIQR/2),
ymin = y-(yIQR/2),
ymax = y+(yIQR/2))
img <- png::readPNG("cindy.png")
g <- grid::rasterGrob(img, interpolate=TRUE, width=unit(1,"npc"), height=unit(1,"npc"))
ggplot(medians, aes(fill=direction,color=direction)) +
annotation_custom(g, xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
geom_rect(aes(xmin=xmin,ymin=ymin,xmax=xmax,ymax=ymax),alpha=.1) +
theme_linedraw() +
scale_x_continuous(limits = c(0,1080), expand = c(0, 0)) +
scale_y_continuous(limits = c(-720,0), expand = c(0, 0)) +
facet_wrap("lang")

Puppies
Get puppy data!
# puppies1 <- read_tsv("../Child Data/_puppies/all puppies group 1 sums.txt", na = "-") %>%
# clean_names() %>%
# select(-c(age, analysis, check_if_want_scatterplot, gender, language)) %>%
# rename(name = x1) %>%
# mutate(mean = rowMeans(.[2:10], na.rm = T)) %>%
# select(name, mean)
#
# puppies2 <- read_tsv("../Child Data/_puppies/all puppies group 2 sums.txt", na = "-") %>%
# clean_names() %>%
# select(-c(age, analysis, check_if_want_scatterplot, gender, language)) %>%
# rename(name = x1) %>%
# mutate(mean = rowMeans(.[2:17], na.rm = T)) %>%
# select(name, mean)
#
# puppies <- rbind(puppies1, puppies2)
#
# participants <- xydata %>%
# select(name, group, gender, lang) %>%
# distinct()
#
# puppies <- left_join(participants, puppies, by = "name")
#
# summary(lm(data = puppies, mean ~ lang))
#
# puppies_se <- filter(puppies, lang == "NSE")
# puppies_nse <- filter(puppies, lang == "SE")
#
# t.test(puppies_se$mean, puppies_nse$mean)
# Let's do this again but preserve puppy-level data
puppies1 <- read_tsv("../Child Data/_puppies/all puppies group 1 sums.txt", na = "-") %>%
clean_names() %>%
select(-c(age, analysis, check_if_want_scatterplot, gender, language)) %>%
rename(name = x1) %>%
gather(key = puppy, value = sec, -name) %>%
mutate(pups = case_when(
str_detect(puppy, "huskies") ~ "huskies",
str_detect(puppy, "golden") ~ "golden",
str_detect(puppy, "wawa") ~ "wawa",
str_detect(puppy, "frisby") ~ "frisby",
str_detect(puppy, "bulldog") ~ "bulldog",
str_detect(puppy, "puppy_jpg") ~ "puppy",
TRUE ~ puppy
))
puppies2 <- read_tsv("../Child Data/_puppies/all puppies group 2 sums.txt", na = "-") %>%
clean_names() %>%
select(-c(age, analysis, check_if_want_scatterplot, gender, language)) %>%
rename(name = x1) %>%
gather(key = puppy, value = sec, -name) %>%
mutate(pups = case_when(
str_detect(puppy, "huskies") ~ "huskies",
str_detect(puppy, "golden") ~ "golden",
str_detect(puppy, "wawa") ~ "wawa",
str_detect(puppy, "frisby") ~ "frisby",
str_detect(puppy, "bulldog") ~ "bulldog",
str_detect(puppy, "puppies") ~ "puppies",
TRUE ~ puppy
))
puppies <- rbind(puppies1,puppies2)
participants <- xydata %>%
select(name, group, gender, lang) %>%
distinct()
puppies <- left_join(participants, puppies, by = "name")
summary(lmer(data = puppies, sec ~ lang + (1|name) + (1|pups)))
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: sec ~ lang + (1 | name) + (1 | pups)
Data: puppies
REML criterion at convergence: 15818.6
Scaled residuals:
Min 1Q Median 3Q Max
-2.9738 -0.5348 -0.0747 0.3391 8.2862
Random effects:
Groups Name Variance Std.Dev.
name (Intercept) 0.8587 0.9267
pups (Intercept) 0.1115 0.3339
Residual 1.8390 1.3561
Number of obs: 4550, groups: name, 26; pups, 7
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 2.1716 0.2655 29.2732 8.178 4.76e-09 ***
langSE -0.5248 0.3759 23.9367 -1.396 0.176
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr)
langSE -0.545
ggplot(puppies, aes(x = lang, y = sec, fill = lang)) + geom_boxplot()

LS0tCnRpdGxlOiAiQmFiaWVzIC0gU3R1ZHkgMiAtIFJlc3VsdHMiCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdGhlbWU6IHNwYWNlbGFiCiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiAyCiAgICB0b2NfZmxvYXQ6IHllcwogICAgZGZfcHJpbnQ6IHBhZ2VkCi0tLQoKVGhpcyBpcyBob3BlZnVsbHkgdGhlIHJlc3VsdHMgc2VjdGlvbiBmb3IgdGhlIFN0dWR5IDIgTlNFICYgU0UgYmFiaWVzIHdhdGNoaW5nIEFTTCBTdG9yaWVzLiBXZSBoYXZlIHR3byBtYWluIGZhY3RvcnM6IAoKMS4gTGFuZ3VhZ2UgKFNpZ24gdi4gRW5nbGlzaCkKMS4gRGlyZWN0aW9uIChGb3J3YXJkIHYuIFJldmVyc2VkKQoKQWdlcyBvZiBiYWJpZXMgYXJlIGZyb20gNSB0byAxNC45OSBtb250aHMuIFRoYXQgbWVhbnMgd2UgbG9zZSB0d28gIm9sZCIgQ09EQSBiYWJpZXMgLSBKYW5pbmUgKDE2IG1vKSBhbmQgemEwMiAoMjMgbW8pLiBUaGUgZGF0YXNldCBhbHNvIGNvbnRhaW5zIGZhY3RvcnMgZm9yIHlvdW5nZXIgdi4gb2xkZXIgYmFiaWVzICpJRiogd2Ugd2FudCB0byBkbyBhZ2UgZ3JvdXAgc3BsaXRzLiBJIGRvIG5vdCByZWNvbW1lbmQgaXQgYmVjYXVzZSB3ZSBsb3NlIGFsbCBzaWduaWZpY2FuY2UgdGhhdCB3YXkgYW5kIHdlIGhhdmUgbW9yZSBwcmVjaXNlIGFnZSBpbmZvcm1hdGlvbiwgYmV0dGVyIHRoYW4gYnJ1dGUgZ3JvdXBzLiAgSUYgd2UgZG8gdXNlIGl0LCB0aGUgYmFieSBhZ2UgZ3JvdXBzIGFyZSBzdWNoOgoKKiBZb3VuZ2VyIGJhYmllcyA9IDUgdG8gOC45OSBtb250aHMKKiBPbGRlciBiYWJpZXMgPSA5LjAgdG8gMTQuOTkgbW9udGhzCgpUbyBza2lwIHRvIHRoZSBYWSBEYXRhLCBnbyBoZXJlLiAKVG8gc2tpcCB0byB0aGUgQU9JL0ZDUiBhbmFseXNpcywgZ28gaGVyZS4gCgojIERlbW9ncmFwaGljcwpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShqYW5pdG9yKQpsaWJyYXJ5KGxtZTQpCmxpYnJhcnkobG1lclRlc3QpCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KGZlYXRoZXIpCmxpYnJhcnkoR0dhbGx5KQoKIyBHcmFiIGRhdGEgdGhhdCB3YXMgcHJvZHVjZWQgaW4gMDNpbXBvcnRjbGVhbmJhYmllcy5SbWQKYmFiaWVzIDwtIHJlYWRfZmVhdGhlcigiY2xlYW5lZGJhYnlleWVkYXRhLmZlYXRoZXIiKSAlPiUKICBtdXRhdGUoYWdlID0gYWdlKjEyKSAlPiUKICBzZWxlY3QocGFydGljaXBhbnQsIGxhbmd1YWdlLCBhZ2UsIGdlbmRlciwgc3RvcnksIGRpcmVjdGlvbiwgbWFyaywgdHJpYWwsIHJlcGV0aXRpb24sIGFvaSwgc2VjcywgcGVyY2VudCkgJT4lCiAgcmVuYW1lKG5hbWUgPSBwYXJ0aWNpcGFudCkgJT4lCiAgbXV0YXRlKGFnZWdyb3VwID0gY2FzZV93aGVuKAogICAgYWdlIDw9IDguOTkgfiAieW91bmdlciIsCiAgICBhZ2UgPj0gOS4wICYgYWdlIDwgMTUgfiAib2xkZXIiCiAgKSkgJT4lCiAgZmlsdGVyKCFpcy5uYShhZ2Vncm91cCkpICU+JQogIG11dGF0ZShsYW5ndWFnZSA9IGNhc2Vfd2hlbigKICAgIGxhbmd1YWdlID09ICJlbmdsaXNoIiB+ICJOU0UiLAogICAgbGFuZ3VhZ2UgPT0ic2lnbiIgfiAiU0UiCiAgKSkgJT4lCiAgcmVuYW1lKGxhbmcgPSBsYW5ndWFnZSkgJT4lCiAgbXV0YXRlKGxhbmcyID0gY2FzZV93aGVuKAogICAgbmFtZSA9PSAiYXVicmV5IENPREEgMTFtIiB+ICJIU0UiLAogICAgbmFtZSA9PSAiR2VtbWFGXzExXzRfMTNfQ09EQSIgfiAiSFNFIiwKICAgIG5hbWUgPT0gIkhhbm5haF9DT0RBXzdtIiB+ICJIU0UiLAogICAgbmFtZSA9PSAia2UxMWVzMTJfN21fTW9tVGVycCIgfiAiTFNFIiwKICAgIG5hbWUgPT0gIk1pbGVzXzE0bV9TRSIgfiAiSFNFIiwKICAgIG5hbWUgPT0gIlBhcmtlciA2IG0gU0lHTklORyIgfiAiSFNFIiwKICAgIG5hbWUgPT0gIlBlbm4gNiBtb250aHMgU0lHTiBFWFBPU0VEIiB+ICJIU0UiLAogICAgbmFtZSA9PSAiVHJpbml0eSA4bSIgfiAiTFNFIiwKICAgIG5hbWUgPT0gIlZpY3RvcmlhMDdfMThfMTciIH4gIkxTRSIsCiAgICBuYW1lID09ICJXZWxsc184bW9zIiB+ICJMU0UiLAogICAgVFJVRSB+IGxhbmcKICApKQojICBmaWx0ZXIobmFtZSAhPSAiVmljdG9yaWEwN18xOF8xNyIpCgpiYWJpZXNpbmZvIDwtIGJhYmllcyAlPiUKICBzZWxlY3QobmFtZSwgbGFuZywgYWdlLCBnZW5kZXIpICU+JQogIGRpc3RpbmN0KCkgJT4lCiAgZ3JvdXBfYnkobGFuZykgJT4lCiAgc3VtbWFyaXNlKE4gPSBuKCksCiAgICAgICAgICAgIGFnZV9tZWFuID0gbWVhbihhZ2UpLAogICAgICAgICAgICBzZCA9IHNkKGFnZSksCiAgICAgICAgICAgIG1pbiA9IG1pbihhZ2UpLAogICAgICAgICAgICBtYXggPSBtYXgoYWdlKSkKCmdlbmRlcnMgPC0gYmFiaWVzICU+JQogIHNlbGVjdChuYW1lLCBsYW5nLCBhZ2UsIGdlbmRlcikgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBncm91cF9ieShsYW5nLCBnZW5kZXIpICU+JQogIHN1bW1hcmlzZShOID0gbigpKSAlPiUKICBzcHJlYWQoZ2VuZGVyLCBOKQoKYmFiaWVzaW5mbyA8LSBsZWZ0X2pvaW4oYmFiaWVzaW5mbywgZ2VuZGVycykgJT4lCiAgc2VsZWN0KGxhbmcsIE4sIEZlbWFsZSwgTWFsZSwgYWdlX21lYW4sIHNkLCBtaW4sIG1heCkgJT4lCiAgcHJpbnQoKQoKYmFiaWVzJGFnZWdyb3VwIDwtIGZjdF9yZWxldmVsKGJhYmllcyRhZ2Vncm91cCwgYygieW91bmdlciIsIm9sZGVyIikpCgoKIyBJRiB3ZSBkbyBhZ2UgZ3JvdXBzLCB1c2UgdGhpcyBjb2RlCiMgCiMgYmFiaWVzaW5mbyA8LSBiYWJpZXMgJT4lCiMgICBzZWxlY3QobmFtZSwgbGFuZywgYWdlLCBhZ2Vncm91cCwgZ2VuZGVyKSAlPiUKIyAgIGRpc3RpbmN0KCkgJT4lCiMgICBncm91cF9ieShsYW5nLCBhZ2Vncm91cCkgJT4lCiMgICBzdW1tYXJpc2UoTiA9IG4oKSwKIyAgICAgICAgICAgICBhZ2VfbWVhbiA9IG1lYW4oYWdlKSwKIyAgICAgICAgICAgICBzZCA9IHNkKGFnZSksCiMgICAgICAgICAgICAgbWluID0gbWluKGFnZSksCiMgICAgICAgICAgICAgbWF4ID0gbWF4KGFnZSkpCiMgCiMgZ2VuZGVycyA8LSBiYWJpZXMgJT4lCiMgICBzZWxlY3QobmFtZSwgbGFuZywgYWdlLCBhZ2Vncm91cCwgZ2VuZGVyKSAlPiUKIyAgIGRpc3RpbmN0KCkgJT4lCiMgICBncm91cF9ieShsYW5nLCBhZ2Vncm91cCwgZ2VuZGVyKSAlPiUKIyAgIHN1bW1hcmlzZShOID0gbigpKSAlPiUKIyAgIHNwcmVhZChnZW5kZXIsIE4pCiMgCiMgYmFiaWVzaW5mbyA8LSBsZWZ0X2pvaW4oYmFiaWVzaW5mbywgZ2VuZGVycykgJT4lCiMgICBzZWxlY3QobGFuZywgYWdlZ3JvdXAsIE4sIEZlbWFsZSwgTWFsZSwgYWdlX21lYW4sIHNkLCBtaW4sIG1heCkgJT4lCiMgICBwcmludCgpCgpgYGAKCiMgR2xvYmFsIExvb2tpbmcKCldlIGNhbGN1bGF0ZWQgcGVyY2VudGFnZXMgKmJhc2VkIG9uIG92ZXJhbGwgY2xpcCBsZW5ndGgqIGFzIHRoZSBkZW5vbWluYXRvci4gSW4gdGhpcyB3YXksIHdlIGNhbiBtZWFuaW5nZnVsbHkgY29udHJhc3QgbG9va2luZyB0aW1lcyBhdCB0aGUgdmlkZW9zICh3aGljaCBhcmUgdmFyaWFibGUgbGVuZ3RocykgYmFzZWQgb24gZGlmZmVyZW50IGZhY3RvcnMuIEJ1dCB3aGVuIHdlIGdvIHRvIEFPSSBhbmFseXNpcyB3ZSBuZWVkIHRvIHJlLWNhbGN1bGF0ZSB0aGUgcGVyY2VudGFnZXMgc28gdGhlIGRlbm9taW5hdG9yIGlzIGJhc2VkIG9uIHRvdGFsIGxvb2tpbmcgdGltZSwgbm90IG92ZXJhbGwgY2xpcCBsZW5ndGguIAoKVGhlIGNoYXJ0IGJlbG93IHNob3dzIGxpdHRsZSBkaWZmZXJlbmNlcyBiYXNlZCBvbiBmYWN0b3JzIEFnZSwgTGFuZ3VhZ2UsIG9yIERpcmVjdGlvbi4gVGhhdCdzIGdvb2QsIG1lYW5zIHRoZSB2aWRlb3Mgd2VyZSBlcXVhbGx5IGVuZ2FnaW5nIGZvciBhbGwgYmFiaWVzLCByaWdodD8gCgpgYGB7cn0KYmFiaWVzJGxhbmcgPC0gYXMuZmFjdG9yKGJhYmllcyRsYW5nKQpiYWJpZXNfb3ZlcmFsbF9sb29raW5nIDwtIGJhYmllcyAlPiUKICBncm91cF9ieShuYW1lLCBhZ2UsIGxhbmcsIGRpcmVjdGlvbiwgc3RvcnksIHJlcGV0aXRpb24pICU+JQogIHN1bW1hcmlzZShwZXJjZW50ID0gc3VtKHBlcmNlbnQpKSAjIGdldHMgdG90YWwgbG9va2luZyBwZXJjZW50IGZvciBlYWNoIHRyaWFsIGZvciBlYWNoIGJhYnkKCiMgVGFibGUgb2YgbWVhbnMKYmFiaWVzX292ZXJhbGxfbG9va2luZyAlPiUgCiAgZ3JvdXBfYnkobmFtZSwgbGFuZywgZGlyZWN0aW9uKSAlPiUKICBzdW1tYXJpc2UocGVyY2VudCA9IG1lYW4ocGVyY2VudCkpICU+JSAjIGdldCBhdmVyYWdlIGxvb2tpbmcgcGVyY2VudCBmb3IgZWFjaCBiYWJ5CiAgZ3JvdXBfYnkobGFuZywgZGlyZWN0aW9uKSAlPiUKICBzdW1tYXJpc2UobWVhbl9wZXJjZW50ID0gbWVhbihwZXJjZW50KSwKICAgICAgICAgICAgY291bnQgPSBuKCksCiAgICAgICAgICAgIHNkID0gc2QocGVyY2VudCksCiAgICAgICAgICAgIHNlID0gc2Qvc3FydChjb3VudCkpICU+JQogIHNlbGVjdCgtc2QpICU+JQogIHByaW50KCkKCmdncGxvdChiYWJpZXNfb3ZlcmFsbF9sb29raW5nLCBhZXMoeCA9IGFnZSwgeSA9IHBlcmNlbnQsIGNvbG9yID0gZGlyZWN0aW9uLCBmaWxsID0gZGlyZWN0aW9uKSkgKyAKICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuNSkgKwogIGZhY2V0X2dyaWQoLiB+IGxhbmcpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFKSArCiAgZ2d0aXRsZSgiVmlkZW8gQXR0ZW50aW9uIikgKwogIHhsYWIoImFnZSAobW9udGhzKSIpICsKICB5bGFiKCJwZXJjZW50IGxvb2tpbmciKSArIAogIHRoZW1lX2J3KCkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDEpLCBsYWJlbHMgPSBwZXJjZW50KSAKCgojIFBsb3QKIyBiYWJpZXNfb3ZlcmFsbF9sb29raW5nICU+JSAKIyAgIGdyb3VwX2J5KGxhbmcsIGRpcmVjdGlvbiwgbmFtZSkgJT4lCiMgICBzdW1tYXJpc2UocGVyY2VudCA9IG1lYW4ocGVyY2VudCkpICU+JSAjIGdldHMgYXZlcmFnZSBsb29raW5nIHBlcmNlbnQgZm9yIGVhY2ggYmFieQojICAgZ3JvdXBfYnkobGFuZywgZGlyZWN0aW9uKSAlPiUKIyAgIHN1bW1hcmlzZShtZWFuX3BlcmNlbnQgPSBtZWFuKHBlcmNlbnQpLCAjIGdldHMgZ3JvdXAgYXZlcmFnZXMKIyAgICAgICAgICAgICBjb3VudCA9IG4oKSwKIyAgICAgICAgICAgICBzZCA9IHNkKHBlcmNlbnQpLAojICAgICAgICAgICAgIHNlID0gc2Qvc3FydChjb3VudCkpICU+JSAKIyAgIGdncGxvdChhZXMoeCA9IGxhbmcsIHkgPSBtZWFuX3BlcmNlbnQsIGZpbGwgPSBkaXJlY3Rpb24pKSArIAojICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArIAojICAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IG1lYW5fcGVyY2VudCAtIHNlLCB5bWF4ID0gbWVhbl9wZXJjZW50ICsgc2UpLCAKIyAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSksIHdpZHRoID0gMC4yNSkgKyAKIyAgIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsMSksIGxhYmVscyA9IHBlcmNlbnQpICsKIyAgIHRoZW1lX21pbmltYWwoKSArIAojICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpKSArCiMgIyAgZmFjZXRfd3JhcCgibGFuZyIpICsKIyAgIGdndGl0bGUoIlZpZGVvIEF0dGVudGlvbiIpICsKIyAgIHhsYWIoIiIpICsKIyAgIHlsYWIoInBlcmNlbnQgbG9va2luZyIpCgojIGJhYmllc19vdmVyYWxsX2xvb2tpbmcgJT4lCiMgICBnZ3Bsb3QoYWVzKHggPSBsYW5nLCB5ID0gcGVyY2VudCwgZmlsbCA9IGRpcmVjdGlvbikpICsKIyAgIGZhY2V0X3dyYXAoImFnZWdyb3VwIikgKyAKIyAgIGdlb21fdmlvbGluKCkKYGBgCgpBIGxpbmVhciBtb2RlbCBzaG93cyB0aGVyZSB3ZXJlIG5vIHNpZ25pZmljYW50IGVmZmVjdHMgb2YgYW55IGZhY3RvcnMuIFdlIGNhbiBjb25jbHVkZSB0aGVyZSB3YXMgbm8gZWZmZWN0IG9uIGhvdyAqbXVjaCogdGhlIGJhYmllcyBsb29rZWQgYXQgdGhlIHN0aW11bGkuICAKCmBgYHtyfQpnbG9iYWxfbG0gPC0gbG1lcihwZXJjZW50IH4gYWdlICsgbGFuZyAqIGRpcmVjdGlvbiArIChkaXJlY3Rpb258bmFtZSkgKyAoZGlyZWN0aW9ufHN0b3J5KSwgZGF0YSA9IGJhYmllc19vdmVyYWxsX2xvb2tpbmcpCnN1bW1hcnkoZ2xvYmFsX2xtKSAKI2dnY29lZihnbG9iYWxfbG0pCmBgYAoKIyBBT0kgTG9va2luZwpOb3cgd2UnbGwgcmUtY2FsY3VsYXRlIHRoZSBwZXJjZW50YWdlcyBzbyB0aGUgZGVub21pbmF0b3IgaXMgYmFzZWQgb24gdG90YWwgbG9va2luZyB0aW1lLiBBbGwgQU9JcyBzaG91bGQgc3VtIHVwIHRvIDEwMCUgZm9yIGVhY2ggdHJpYWwgYW5kIGVhY2ggYmFieS4gTmV4dCBsZXQncyBtYWtlIGEgYm94cGxvdCBvZiBhbGwgQU9Jcy4gCgpgYGB7cn0KI1JlY2FsY3VsYXRlIHBlcmNlbnQKYmFiaWVzIDwtIGJhYmllcyAlPiUKICBzZWxlY3QoLXBlcmNlbnQpICU+JQogIGdyb3VwX2J5KG5hbWUsIGxhbmcsIGFnZWdyb3VwLCBhZ2UsIGRpcmVjdGlvbiwgc3RvcnksIG1hcmssIHRyaWFsLCByZXBldGl0aW9uLCBnZW5kZXIpICU+JQogIG11dGF0ZSh0b3RhbHNlYyA9IHN1bShzZWNzKSkgJT4lCiAgZ3JvdXBfYnkobmFtZSwgbGFuZywgYWdlZ3JvdXAsIGFnZSwgZGlyZWN0aW9uLCBzdG9yeSwgbWFyaywgdHJpYWwsIHJlcGV0aXRpb24sIGdlbmRlciwgYW9pKSAlPiUKICBtdXRhdGUocGVyY2VudCA9IHNlY3MvdG90YWxzZWMpCgojIEJveHBsb3QKYmFiaWVzICU+JQogIGdncGxvdChhZXMoeCA9IGFvaSwgeSA9IHBlcmNlbnQsIGZpbGwgPSBkaXJlY3Rpb24pKSArIAogIGdlb21fYm94cGxvdCgpICsKICBnZ3RpdGxlKCJBT0kgQXR0ZW50aW9uIikgKwogIHRoZW1lX2J3KCkgKyAKICB4bGFiKCIiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NDUsIGhqdXN0ID0gMSksCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCwgbGltaXRzID0gYygwLDEpKQpgYGAKSXQgYXBwZWFycyB0d28gaW1wb3J0YW50IEFPSXMgYXJlIE1pZENoZXN0VG9wIGFuZCBNaWRGYWNlQm90dG9tLiBMZXQncyBsb29rIGFnYWluIG9ubHkgYXQgbWlkbGluZSBBT0lzOgoKYGBge3J9Cm1pZGxpbmUgPSBjKCJCZWxseSIsIkJlbG93Q2hlc3QiLCJNaWRDaGVzdEJvdHRvbSIsIk1pZENoZXN0Q2VudGVyIiwiTWlkQ2hlc3RUb3AiLAogICAgICAgICAgICAiTWlkRmFjZUJvdHRvbSIsIk1pZEZhY2VDZW50ZXIiLCJNaWRGYWNlVG9wIikKYmFiaWVzICU+JQogIGZpbHRlcihhb2kgJWluJSBtaWRsaW5lKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBhb2ksIHkgPSBwZXJjZW50LCBmaWxsID0gZGlyZWN0aW9uKSkgKyAKICBnZW9tX2JveHBsb3QoKSArCiAgZ2d0aXRsZSgiTWlkbGluZSBBT0kgQXR0ZW50aW9uIikgKwogIHRoZW1lX2J3KCkgKyAKICB4bGFiKCIiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NDUsIGhqdXN0ID0gMSksCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCwgbGltaXRzID0gYygwLDEpKQpgYGAKCkknbSBnb2luZyB0byBydW4gbGluZWFyIG1vZGVscyB3aXRoIG9ubHkgTWlkQ2hlc3RUb3Agb3IgTWlkRmFjZUJvdHRvbSwgYW5kIHNlZSB3aGF0IGhhcHBlbnMuIE5vIGFnZSBpbnRlcmFjdGlvbnMuCgoqKk1pZENoZXN0VG9wOioqCgoqIFNpZ25pZmljYW50IGVmZmVjdCBvZiBhZ2UgKHAgPSAwLjAwNCkgLSBvbGRlciBiYWJpZXMgbG9vayBhdCBNaWRDaGVzdFRvcCBBT0kgbW9yZS4KKiBTaWduaWZpY2FudCBlZmZlY3Qgb2YgbGFuZ3VhZ2UgKHAgPSAwLjAwNikgLSBOU0UgYmFiaWVzIGxvb2sgKzE0LjYlIG1vcmUgdGhhbiBTRSBiYWJpZXMuIAoqIFNpZ25pZmljYW50IGVmZmVjdCBvZiBkaXJlY3Rpb24gKHAgPSAwLjA0NikgLSBCYWJpZXMgbG9vayBhYm91dCA0LjUlIGxlc3MgZm9yIHJldmVyc2VkCiogTm8gbGFuZ3VhZ2UgWCBkaXJlY3Rpb24gaW50ZXJhY3Rpb24uIAoKKipNaWRGYWNlQm90dG9tOioqIAoKKiBObyBlZmZlY3Qgb2YgYWdlCiogU2lnbmlmaWNhbnQgZWZmZWN0IG9mIGxhbmd1YWdlIChwID0gMC4wMDQpIC0gU0UgYmFiaWVzIGxvb2sgKzIxJSBtb3JlIHRoYW4gTlNFIGJhYmllcy4KKiBNYXJnaW5hbCBlZmZlY3Qgb2YgbGFuZ3VhZ2UgKHAgPSAwLjA3MykgLSBCYWJpZXMgbG9vayBhYm91dCAyJSBtb3JlIGZvciByZXZlcnNlZC4gCiogTm8gbGFuZ3VhZ2UgWCBkaXJlY3Rpb24gaW50ZXJhY3Rpb24uCgpgYGB7cn0KYmFiaWVzICU+JQogIGZpbHRlcihhb2kgJWluJSBjKCJNaWRGYWNlQm90dG9tIiwiTWlkQ2hlc3RUb3AiKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gYWdlLCB5ID0gcGVyY2VudCwgY29sb3IgPSBkaXJlY3Rpb24sIGZpbGwgPSBkaXJlY3Rpb24pKSArIAogIGdlb21faml0dGVyKGFscGhhID0gMC41KSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDEpLCBsYWJlbHMgPSBwZXJjZW50KSArCiAgdGhlbWVfYncoKSArIAojICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCkpICsKICBmYWNldF9ncmlkKGFvaSB+IGxhbmcpICsKICBnZ3RpdGxlKCJBT0kgQXR0ZW50aW9uIikgKwogIHhsYWIoIiIpICsKICB5bGFiKCJwZXJjZW50IGxvb2tpbmciKQoKbWlkY2hlc3R0b3BfbG0gPC0gbG1lcihwZXJjZW50IH4gYWdlICsgbGFuZyAqIGRpcmVjdGlvbiArICgxfG5hbWUpICsgKDF8c3RvcnkpLCBkYXRhID0gZmlsdGVyKGJhYmllcywgYW9pID09ICJNaWRDaGVzdFRvcCIpKQpzdW1tYXJ5KG1pZGNoZXN0dG9wX2xtKQojZ2djb2VmKG1pZGNoZXN0dG9wX2xtKQoKbWlkZmFjZWJvdHRvbV9sbSA8LSBsbWVyKHBlcmNlbnQgfiBhZ2UgKyBsYW5nICogZGlyZWN0aW9uICsgKDF8bmFtZSkgKyAoMXxzdG9yeSksIGRhdGEgPSBmaWx0ZXIoYmFiaWVzLCBhb2kgPT0gIk1pZEZhY2VCb3R0b20iKSkKc3VtbWFyeShtaWRmYWNlYm90dG9tX2xtKQojZ2djb2VmKG1pZGZhY2Vib3R0b21fbG0pCgojIEJhciBjaGFydAojIGJhYmllcyAlPiUKIyAgIGZpbHRlcihhb2kgJWluJSBjKCJNaWRGYWNlQm90dG9tIiwiTWlkQ2hlc3RUb3AiKSkgJT4lCiMgICBncm91cF9ieShhZ2Vncm91cCwgbGFuZywgZGlyZWN0aW9uLCBuYW1lLCBhb2kpICU+JQojICAgc3VtbWFyaXNlKHBlcmNlbnQgPSBtZWFuKHBlcmNlbnQpKSAlPiUgIyBnZXRzIGF2ZXJhZ2UgbG9va2luZyBwZXJjZW50IGZvciBlYWNoIGJhYnkKIyAgIGdyb3VwX2J5KGFnZWdyb3VwLCBsYW5nLCBkaXJlY3Rpb24sIGFvaSkgJT4lCiMgICBzdW1tYXJpc2UobWVhbl9wZXJjZW50ID0gbWVhbihwZXJjZW50KSwgIyBnZXRzIGdyb3VwIGF2ZXJhZ2VzCiMgICAgICAgICAgICAgY291bnQgPSBuKCksCiMgICAgICAgICAgICAgc2QgPSBzZChwZXJjZW50KSwKIyAgICAgICAgICAgICBzZSA9IHNkL3NxcnQoY291bnQpKSAlPiUgCiMgICBnZ3Bsb3QoYWVzKHggPSBsYW5nLCB5ID0gbWVhbl9wZXJjZW50LCBmaWxsID0gZGlyZWN0aW9uKSkgKyAKIyAgIGdlb21fY29sKHBvc2l0aW9uID0gImRvZGdlIikgKyAKIyAgIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBtZWFuX3BlcmNlbnQgLSBzZSwgeW1heCA9IG1lYW5fcGVyY2VudCArIHNlKSwgCiMgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpLCB3aWR0aCA9IDAuMjUpICsgCiMgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDEpLCBsYWJlbHMgPSBwZXJjZW50KSArCiMgICB0aGVtZV9taW5pbWFsKCkgKyAKIyAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSkgKwojICAgZmFjZXRfZ3JpZChhb2kgfiBhZ2Vncm91cCkgKwojICAgZ2d0aXRsZSgiVmlkZW8gQXR0ZW50aW9uIikgKwojICAgeGxhYigiIikgKwojICAgeWxhYigicGVyY2VudCBsb29raW5nIikKYGBgCgoKIyBGYWNlLUNoZXN0IFJhdGlvCk5leHQsIHdlJ2xsIGRlZmluZSBhIEZhY2UtQ2hlc3QgUmF0aW8gKEZDUikgc3VjaCB0aGF0OgoKMS4gTWlkRmFjZUNlbnRlciwgTWlkRmFjZUJvdHRvbSA9IEZhY2UKMS4gTWlkQ2hlc3RUb3AsIE1pZENoZXN0Q2VudGVyLCBNaWRDaGVzdEJvdHRvbSwgQmVsb3dDaGVzdCA9IENoZXN0CjEuIEZDUiA9IGZhY2UgLSBjaGVzdCAvIGZhY2UgKyBjaGVzdAoKV2UgZGlkIG5vdCBpbmNsdWRlIEJlbGx5IG9yIE1pZEZhY2VUb3AgYmVjYXVzZSBvZiB2ZXJ5IGxvdyBsb29raW5nIHJhdGVzIGFjY29yZGluZyB0byB0aGUgYm94cGxvdHMgYWJvdmUuCgpgYGB7cn0KYmFiaWVzX2ZjciA8LSBiYWJpZXMgJT4lCiAgc3ByZWFkKGFvaSxwZXJjZW50KSAlPiUKICBncm91cF9ieShuYW1lLCBhZ2UsIGFnZWdyb3VwLCBsYW5nLCBnZW5kZXIsIGRpcmVjdGlvbiwgc3RvcnksIHJlcGV0aXRpb24pICU+JQogIHN1bW1hcmlzZShmYWNlID0gc3VtKE1pZEZhY2VDZW50ZXIsIE1pZEZhY2VCb3R0b20sIG5hLnJtID0gVFJVRSksCiAgICAgICAgIGNoZXN0ID0gc3VtKE1pZENoZXN0VG9wLCBNaWRDaGVzdENlbnRlciwgTWlkQ2hlc3RCb3R0b20sIEJlbG93Q2hlc3QsIG5hLnJtID0gVFJVRSksCiAgICAgICAgIGZjciA9IChmYWNlIC0gY2hlc3QpIC8gKGZhY2UgKyBjaGVzdCkpCgojIFRhYmxlIG9mIG1lYW5zCmJhYmllc19mY3IgJT4lIAogIGdyb3VwX2J5KGxhbmcsIGRpcmVjdGlvbiwgbmFtZSkgJT4lCiAgc3VtbWFyaXNlKGZjciA9IG1lYW4oZmNyKSkgJT4lICMgZ2V0cyBhdmVyYWdlIGxvb2tpbmcgcGVyY2VudCBmb3IgZWFjaCBiYWJ5CiAgZ3JvdXBfYnkobGFuZywgZGlyZWN0aW9uKSAlPiUKICBzdW1tYXJpc2UobWVhbl9mY3IgPSBtZWFuKGZjciksICMgZ2V0cyBncm91cCBhdmVyYWdlcwogICAgICAgICAgICBjb3VudCA9IG4oKSwKICAgICAgICAgICAgc2QgPSBzZChmY3IpLAogICAgICAgICAgICBzZSA9IHNkL3NxcnQoY291bnQpKSAlPiUKICBzZWxlY3QoLXNkKSAlPiUKICBwcmludCgpCgojIFBsb3QKZ2dwbG90KGJhYmllc19mY3IsIGFlcyh4ID0gYWdlLCB5ID0gZmNyLCBjb2xvciA9IGRpcmVjdGlvbiwgZmlsbCA9IGRpcmVjdGlvbikpICsgCiAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC0xLDEpKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGZhY2V0X2dyaWQoLiB+IGxhbmcpICsKICBnZ3RpdGxlKCJGYWNlLUNoZXN0IFJhdGlvcyIpICsKICB4bGFiKCIiKSArCiAgeWxhYigiRkNSIikKCiMgQmFyIGNoYXJ0CiMgYmFiaWVzX2ZjciAlPiUgCiMgICBncm91cF9ieShhZ2Vncm91cCwgbGFuZywgZGlyZWN0aW9uLCBuYW1lKSAlPiUKIyAgIHN1bW1hcmlzZShmY3IgPSBtZWFuKGZjcikpICU+JSAjIGdldHMgYXZlcmFnZSBsb29raW5nIHBlcmNlbnQgZm9yIGVhY2ggYmFieQojICAgZ3JvdXBfYnkoYWdlZ3JvdXAsIGxhbmcsIGRpcmVjdGlvbikgJT4lCiMgICBzdW1tYXJpc2UobWVhbl9mY3IgPSBtZWFuKGZjciksICMgZ2V0cyBncm91cCBhdmVyYWdlcwojICAgICAgICAgICAgIGNvdW50ID0gbigpLAojICAgICAgICAgICAgIHNkID0gc2QoZmNyKSwKIyAgICAgICAgICAgICBzZSA9IHNkL3NxcnQoY291bnQpKSAlPiUgCiMgICBnZ3Bsb3QoYWVzKHggPSBsYW5nLCB5ID0gbWVhbl9mY3IsIGZpbGwgPSBkaXJlY3Rpb24pKSArIAojICAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArIAojICAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IG1lYW5fZmNyIC0gc2UsIHltYXggPSBtZWFuX2ZjciArIHNlKSwgCiMgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpLCB3aWR0aCA9IDAuMjUpICsgCiMgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtMSwxKSkgKwojICAgdGhlbWVfbWluaW1hbCgpICsgCiMgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCkpICsKIyAgIGZhY2V0X3dyYXAoImFnZWdyb3VwIikgKwojICAgZ2d0aXRsZSgiRmFjZS1DaGVzdCBSYXRpb3MiKSArCiMgICB4bGFiKCIiKSArCiMgICB5bGFiKCJGQ1IiKQpgYGAKCldoYXQgd2lsbCBhIGxpbmVhciBtaXhlZCBtb2RlbCB0ZWxsIHVzPyAod2l0aCBubyBhZ2UgaW50ZXJhY3Rpb25zKQoKKiBObyBlZmZlY3Qgb2YgYWdlLiBJbnRlcmVzdGluZy4gTWF5YmUgYmVjYXVzZSB3ZSBkb24ndCBoYXZlIHRoYXQgbWFueSBiYWJpZXMuIAoqIFN0cm9uZyBlZmZlY3Qgb2YgbGFuZ3VhZ2U6IFNFIGJhYmllcyBoYXZlIG92ZXJhbGwgKzAuNTAgRkNSIHRoYW4gTlNFIGJhYmllcyAocCA9IDAuMDA4KTsgaW4gb3RoZXIgd29yZHMsIHRoZXkgYXJlIG1vcmUgYXR0cmFjdGVkIHRvIHRoZSBmYWNlLiAKKiBFZmZlY3Qgb2YgZGlyZWN0aW9uOiBSZXZlcnNhbCAqaW5jcmVhc2VzKiBGQ1IgYnkgKzAuMTIgYWNyb3NzIGFsbCBiYWJpZXMgKHAgPSAwLjAzMikuIEludGVyZXN0aW5nLgoqIFdlYWsgbGFuZ3VhZ2UgeCBkaXJlY3Rpb24gaW50ZXJhY3Rpb24uIEl0IHNlZW1zIE5TRSBiYWJpZXMgaGF2ZSBhIGJpZ2dlciByZXZlcnNhbCBlZmZlY3QgdGhhbiBTRSBiYWJpZXM/IFRyeWluZyB0byBqdWRnZSBmcm9tIHRoZSBoZWF0IG1hcHMuIChwID0gMC4wOTUpLiBCVXQgaXQncyBzbyB3ZWFrIHNvIHBvc3NpYmx5IG5vdCB3b3J0aCBtZW50aW9uaW5nLgoKCmBgYHtyfQpmY3JfbG0gPC0gbG1lcihmY3IgfiBhZ2UgKyBsYW5nICogZGlyZWN0aW9uICsgKDF8bmFtZSkgKyAoMXxzdG9yeSksIGRhdGEgPSBiYWJpZXNfZmNyKQpzdW1tYXJ5KGZjcl9sbSkKI2dnY29lZihmY3JfbG0pCmBgYAoKIyBIZWF0IE1hcHMKQW5kIG5vdyBoZWF0IG1hcHMhCgpgYGB7cn0KaGVhdG1hcF9iYWJpZXMgPC0gYmFiaWVzICU+JQogIGZpbHRlcihhb2kgJWluJSBtaWRsaW5lKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZ3JvdXBfYnkobGFuZywgbmFtZSwgZGlyZWN0aW9uLCBhb2kpICU+JQogIHN1bW1hcmlzZShwZXJjZW50ID0gbWVhbihwZXJjZW50LCBuYS5ybT1UUlVFKSkgJT4lCiAgZ3JvdXBfYnkobGFuZywgZGlyZWN0aW9uLCBhb2kpICU+JQogIHN1bW1hcmlzZShwZXJjZW50ID0gbWVhbihwZXJjZW50LCBuYS5ybT1UUlVFKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZShhb2kgPSBmYWN0b3IoYW9pLCBsZXZlbHMgPSBjKCJCZWxseSIsIkJlbG93Q2hlc3QiLCJNaWRDaGVzdEJvdHRvbSIsIk1pZENoZXN0Q2VudGVyIiwiTWlkQ2hlc3RUb3AiLAogICAgICAgICAgICAiTWlkRmFjZUJvdHRvbSIsIk1pZEZhY2VDZW50ZXIiLCJNaWRGYWNlVG9wIikpKQoKZ2dwbG90KGhlYXRtYXBfYmFiaWVzLCBhZXMoeCA9IGxhbmcsIHkgPSBhb2kpKSArCiAgZ2VvbV90aWxlKGFlcyhmaWxsPXBlcmNlbnQpLGNvbG9yPSJsaWdodGdyYXkiLG5hLnJtPVRSVUUpICsgCiMgIHNjYWxlX2ZpbGxfdmlyaWRpcyhvcHRpb24gPSAidmlyaWRpcyIsIGRpcmVjdGlvbj0tMSwgbGltaXRzID0gYygwLC43KSwgbGFiZWxzID0gcGVyY2VudCwgbmFtZSA9ICJsb29raW5nIHRpbWUiKSArCiAgICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICIjZmZmZmZmIiwgaGlnaCA9ICIjMDg1MTljIiwgc3BhY2UgPSAiTGFiIiwgbGltaXRzID0gYygwLC40NTEpLCBsYWJlbHMgPSBwZXJjZW50LCBuYW1lID0gImxvb2tpbmcgdGltZSIsIG5hLnZhbHVlID0gImdyZXk1MCIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExLCBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiaXRhbGljIiksIAogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gIndoaXRlIiwgZmlsbCA9ICJ3aGl0ZSIpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAid2hpdGUiKSkgKwogIGZhY2V0X2dyaWQoLiB+IGRpcmVjdGlvbikgKwogIHlsYWIoIiIpICsgeGxhYigiIikgKyBnZ3RpdGxlKCJFeWUgR2F6ZSBIZWF0IE1hcCwgYnkgRGlyZWN0aW9uIikgKyAKICBzY2FsZV95X2Rpc2NyZXRlKGV4cGFuZD1jKDAsMCkpICsKICBzY2FsZV94X2Rpc2NyZXRlKGV4cGFuZCA9IGMoMCwwKSkKCmdncGxvdChoZWF0bWFwX2JhYmllcywgYWVzKHggPSBkaXJlY3Rpb24sIHkgPSBhb2kpKSArCiAgZ2VvbV90aWxlKGFlcyhmaWxsPXBlcmNlbnQpLGNvbG9yPSJsaWdodGdyYXkiLG5hLnJtPVRSVUUpICsgCiMgIHNjYWxlX2ZpbGxfdmlyaWRpcyhvcHRpb24gPSAidmlyaWRpcyIsIGRpcmVjdGlvbj0tMSwgbGltaXRzID0gYygwLC43KSwgbGFiZWxzID0gcGVyY2VudCwgbmFtZSA9ICJsb29raW5nIHRpbWUiKSArCiAgICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICIjZmZmZmZmIiwgaGlnaCA9ICIjMDg1MTljIiwgc3BhY2UgPSAiTGFiIiwgbGltaXRzID0gYygwLC40NTEpLCBsYWJlbHMgPSBwZXJjZW50LCBuYW1lID0gImxvb2tpbmcgdGltZSIsIG5hLnZhbHVlID0gImdyZXk1MCIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExLCBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiaXRhbGljIiksIAogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gIndoaXRlIiwgZmlsbCA9ICJ3aGl0ZSIpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAid2hpdGUiKSkgKwogIGZhY2V0X2dyaWQoLiB+IGxhbmcpICsKICB5bGFiKCIiKSArIHhsYWIoIiIpICsgZ2d0aXRsZSgiRXllIEdhemUgSGVhdCBNYXAsIGJ5IExhbmd1YWdlIikgKyAKICBzY2FsZV95X2Rpc2NyZXRlKGV4cGFuZD1jKDAsMCkpICsKICBzY2FsZV94X2Rpc2NyZXRlKGV4cGFuZCA9IGMoMCwwKSkKYGBgCgojIERpZmZlcmVudCBXYXlzIHRvIFZpc3VhbGl6ZSBSZXZlcnNhbApJIHdhbnQgdG8gdHJ5IHRvIHZpc3VhbGl6ZSByZXZlcnNhbCBlZmZlY3RzIGEgZGlmZmVyZW50IHdheS4gTWF5YmUgdGhpcy4gCgpgYGB7cn0KIyBHZXQgcGFydGljaXBhbnQtbGV2ZWwgZGF0YQpiYWJpZXNfZmNyMiA8LSBiYWJpZXNfZmNyICU+JQogIGdyb3VwX2J5KG5hbWUsIGFnZSwgbGFuZywgZGlyZWN0aW9uKSAlPiUKICBzdW1tYXJpc2UoZmNyID0gbWVhbihmY3IpKQoKIyByZXZlcnNhbF9lZmZlY3RfbG0gPC0gbG1lcihmY3IgfiBhZ2UgKyBsYW5nICogZGlyZWN0aW9uICsgKDF8bmFtZSksIGRhdGEgPSBiYWJpZXNfZmNyMikKIyBzdW1tYXJ5KHJldmVyc2FsX2VmZmVjdF9sbSkKCmdncGxvdChiYWJpZXNfZmNyMiwgYWVzKHggPSBkaXJlY3Rpb24sIHkgPSBmY3IsIGNvbG9yID0gbGFuZywgZmlsbCA9IGxhbmcpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gbmFtZSkpICsKICBmYWNldF9ncmlkKC4gfiBsYW5nKSArIAogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC0xLDEpKSArCiAgdGhlbWVfYncoKQoKYGBgCgpPciBhIHJldmVyc2FsIGVmZmVjdCBjaGFydD8gT2theSwgc28gdGhpcyBjaGFydCB0ZWxscyB1cyBvdmVyYWxsIHRoZXJlIHJlYWxseSB3YXNuJ3QgbXVjaCBvZiBhIHJldmVyc2FsIGVmZmVjdCBmb3IgU0UgYmFiaWVzLCB0aGV5J3JlIGFsbCBob3ZlcmluZyBhcm91bmQgMC4gSW50ZXJlc3RpbmcuIFdoaWxlIHRoZXJlIHNlZW1zIHRvIGJlIGEgcmV2ZXJzYWwgZWZmZWN0IGZvciBOU0UgYmFiaWVzIHdoZXJlIHRoZXkgbG9vayBhdCB0aGUgZmFjZSBtb3JlIGR1cmluZyByZXZlcnNlZCBzdG9yaWVzISAKCmBgYHtyfQojIEdldCBwYXJ0aWNpcGFudC1sZXZlbCBkYXRhCmJhYmllc19mY3IzIDwtIGJhYmllc19mY3IyICU+JQogIHNwcmVhZChkaXJlY3Rpb24sIGZjcikgJT4lCiAgZ3JvdXBfYnkobmFtZSwgYWdlLCBsYW5nKSAlPiUKICBzdW1tYXJpc2UoZGlmZiA9IGZvcndhcmQgLSByZXZlcnNlZCkKCmdncGxvdChiYWJpZXNfZmNyMywgYWVzKHggPSBhZ2UsIHkgPSBkaWZmLCBjb2xvciA9IGxhbmcpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTEsMSkpICsKICB0aGVtZV9idygpICsKICBnZ3RpdGxlKCJSZXZlcnNhbCBFZmZlY3QiKSArCiAgeWxhYigiRm9yd2FyZCBGQ1IgLSBSZXZlcnNlZCBGQ1IiKQpgYGAKClRoaXMgYW5hbHlzaXMgb2Ygd2l0aGluLXN1YmplY3QgdmFyaWF0aW9uIGhlcmU6IAoKYGBge3J9CiMgRmlyc3QgZ2V0IHRoZSBtZWFuIG9mIGVhY2ggdHJpYWwsIFRIRU4gdGhlIHBhcnRpY2lwYW50LWxldmVsIG1lYW5zCndpdGhpbl9zdWJqZWN0cyA8LSBiYWJpZXNfZmNyICU+JQogIGdyb3VwX2J5KG5hbWUsIGxhbmcsIGRpcmVjdGlvbiwgc3RvcnksIHJlcGV0aXRpb24pICU+JQogIHN1bW1hcmlzZShmY3IgPSBtZWFuKGZjciwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgY291bnQgPSBuKCkpICU+JQogIGdyb3VwX2J5KG5hbWUsIGxhbmcsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKGZjciwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgc2UgPSBzZChmY3IsIG5hLnJtID0gVFJVRSkvc3FydChuKCkpLAogICAgICAgICAgICBjb3VudCA9IG4oKSkKIyBUaGVuIHNwcmVhZCBvdXQgbWVhbiBhbmQgU0UgY29sdW1ucyBieSBkaXJlY3Rpb24Kd2l0aGluX3N1YmplY3RzX21lYW5zIDwtIHdpdGhpbl9zdWJqZWN0cyAlPiUKICBzZWxlY3QoLXNlLCAtY291bnQpICU+JQogIHNwcmVhZChkaXJlY3Rpb24sIG1lYW4sIHNlcCA9ICJfIikKd2l0aGluX3N1YmplY3RzX3NlIDwtIHdpdGhpbl9zdWJqZWN0cyAlPiUKICBzZWxlY3QoLW1lYW4sIC1jb3VudCkgJT4lCiAgc3ByZWFkKGRpcmVjdGlvbiwgc2UsIHNlcCA9ICJTRSIpCndpdGhpbl9zdWJqZWN0cyA8LSBsZWZ0X2pvaW4od2l0aGluX3N1YmplY3RzX21lYW5zLCB3aXRoaW5fc3ViamVjdHNfc2UsIGJ5ID0gYygibmFtZSIsImxhbmciKSkKCiMgTm93IGxldCdzIHBsb3QKbGltcyA8LSBjKC0xLDEpCndpdGhpbl9zdWJqZWN0cyAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkaXJlY3Rpb25fZm9yd2FyZCwgeSA9IGRpcmVjdGlvbl9yZXZlcnNlZCwgY29sb3IgPSBsYW5nKSkgKwogIGdlb21fYWJsaW5lKCkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsgCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1kaXJlY3Rpb25fcmV2ZXJzZWQtZGlyZWN0aW9uU0VyZXZlcnNlZCwgeW1heD1kaXJlY3Rpb25fcmV2ZXJzZWQrZGlyZWN0aW9uU0VyZXZlcnNlZCkpICsKICBnZW9tX2Vycm9yYmFyaChhZXMoeG1pbj1kaXJlY3Rpb25fZm9yd2FyZC1kaXJlY3Rpb25TRWZvcndhcmQsIHhtYXg9ZGlyZWN0aW9uX2ZvcndhcmQrZGlyZWN0aW9uU0Vmb3J3YXJkKSkgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKGFzcGVjdC5yYXRpbyA9IDEpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoImZvcndhcmQiLCBsaW1pdHMgPSBjKC0xLDEpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKCJyZXZlcnNlZCIsIGxpbWl0cyA9IGMoLTEsMSkpICsKICBnZ3RpdGxlKCJGQ1IgTWVhbnMiKSArCiAgZmFjZXRfd3JhcCgibGFuZyIpCmBgYAoKQW5kIGEgY2xhc3NpYyBib3gvZXJyb3IgcGxvdCB3aXRoIGFnZSBjb2xsYXBzZWQuIAoKYGBge3J9CmJhYmllc19mY3IyICU+JQogIGdyb3VwX2J5KGxhbmcsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKGZjcl9tZWFuID0gbWVhbihmY3IpLAogICAgICAgICAgICBzZCA9IHNkKGZjciksCiAgICAgICAgICAgIG4gPSBuKCksCiAgICAgICAgICAgIHNlID0gc2Qvc3FydChuKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gbGFuZywgeSA9IGZjcl9tZWFuLCBmaWxsID0gZGlyZWN0aW9uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsgCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IGZjcl9tZWFuLXNlLCB5bWF4ID0gZmNyX21lYW4rc2UpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuOSksIHdpZHRoID0gMC4yKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTAuNSwgMC41KSkgKwogIHRoZW1lX2xpbmVkcmF3KCkKCmBgYAoKIyBEaXNjdXNzaW9uIHJlIEFPSS9hbmF0b21pY2FsIGRhdGEKVGhlIGJpZ2dlc3QgY2hhbmdlIGlzIHdlIGxvc3QgdGhlIGludGVyYWN0aW9uIGJldHdlZW4gbGFuZ3VhZ2UgYW5kIGRpcmVjdGlvbi4gRm9yIHRoZSBJQ1NMQSBhYnN0cmFjdCB3ZSByZXBvcnRlZCBhIHN0cm9uZyBpbnRlcmFjdGlvbiAocCA9IDAuMDEpLCBidXQgbm93IGl0J3MgcCA9IDAuMTAuIFNob290LiAKClRoZSBpbnRlcnByZXRhdGlvbiBoZXJlIGlzIHRoYXQ6CgoqIEFsbCBiYWJpZXMgbG9va2VkIGVxdWFsbHkgYXQgYWxsIHZpZGVvcyByZWdhcmRsZXNzIG9mIGxhbmd1YWdlIG9yIGRpcmVjdGlvbi4gR29vZCEKKiBTRSBiYWJpZXMgYXJlIHN0cm9uZ2VyIGZhY2UtbG9va2VycyB0aGFuIE5TRSBiYWJpZXMuIChTYW1lIGFzIElDU0xBKQoqIFJldmVyc2FsIGFwcGVhcnMgdG8gYWZmZWN0IE5TRSBiYWJpZXMgbW9yZSB0aGFuIFNFIGJhYmllcz8gKE1hcmdpbmFsKS4gVGhpcyBpcyB1bmxpa2UgSUNTTEEuIAoKYGBge3IgZXZhbD1GQUxTRSwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyLCBpbmNsdWRlPUZBTFNFfQojIENvcnJlbGF0aW9ucwoKIyBMZXQncyB0cnkgY29ycmVsYXRpb25zCmJhYmllc19uc2UgPC0gYmFiaWVzICU+JSAKICBmaWx0ZXIoYW9pICVpbiUgbWlkbGluZSkgJT4lCiAgZmlsdGVyKGxhbmcgPT0gIk5TRSIpICU+JQogIGdyb3VwX2J5KG5hbWUsIGRpcmVjdGlvbiwgYW9pKSAlPiUgCiAgc3VtbWFyaXNlKHBlcmNlbnQgPSBtZWFuKHBlcmNlbnQpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKGRpcmVjdGlvbiA9IGNhc2Vfd2hlbigKICAgIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIgfiAiZnciLAogICAgZGlyZWN0aW9uID09ICJyZXZlcnNlZCIgfiAicnYiCiAgKSkgJT4lIAogIHVuaXRlKGFvaTIsIGRpcmVjdGlvbiwgYW9pLCBzZXAgPSAiXyIpICU+JQogIHNwcmVhZChhb2kyLCBwZXJjZW50KSAlPiUKICBzZWxlY3QoLW5hbWUpCgpiYWJpZXNfc2UgPC0gYmFiaWVzICU+JSAKICBmaWx0ZXIoYW9pICVpbiUgbWlkbGluZSkgJT4lCiAgZmlsdGVyKGxhbmcgPT0gIlNFIikgJT4lCiAgZ3JvdXBfYnkobmFtZSwgZGlyZWN0aW9uLCBhb2kpICU+JSAKICBzdW1tYXJpc2UocGVyY2VudCA9IG1lYW4ocGVyY2VudCkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUoZGlyZWN0aW9uID0gY2FzZV93aGVuKAogICAgZGlyZWN0aW9uID09ICJmb3J3YXJkIiB+ICJmdyIsCiAgICBkaXJlY3Rpb24gPT0gInJldmVyc2VkIiB+ICJydiIKICApKSAlPiUgCiAgdW5pdGUoYW9pMiwgZGlyZWN0aW9uLCBhb2ksIHNlcCA9ICJfIikgJT4lCiAgc3ByZWFkKGFvaTIsIHBlcmNlbnQpICU+JQogIHNlbGVjdCgtbmFtZSkKCmdnY29ycihiYWJpZXNfbnNlLCBsYWJlbCA9IFRSVUUsIGxhYmVsX3NpemUgPSA1LCBsYWJlbF9yb3VuZCA9IDIsIGxhYmVsX2FscGhhID0gVFJVRSwgaGp1c3QgPSAwLjksIHNpemUgPSA1LCBjb2xvciA9ICJncmV5NTAiLCBsYXlvdXQuZXhwID0gMSkgKyBnZ3RpdGxlKCJOU0UiKQoKZ2djb3JyKGJhYmllc19zZSwgbGFiZWwgPSBUUlVFLCBsYWJlbF9zaXplID0gNSwgbGFiZWxfcm91bmQgPSAyLCBsYWJlbF9hbHBoYSA9IFRSVUUsIGhqdXN0ID0gMC45LCBzaXplID0gNSwgY29sb3IgPSAiZ3JleTUwIiwgbGF5b3V0LmV4cCA9IDEpICsgZ2d0aXRsZSgiU0UiKQoKbGlicmFyeShjb3JycikKYmFiaWVzX25zZSAlPiUgY29ycmVsYXRlKCkgJT4lIG5ldHdvcmtfcGxvdChtaW5fY29yPTAuNikgKyBnZ3RpdGxlKCJOU0UgQmFiaWVzIikKYmFiaWVzX3NlICU+JSBjb3JyZWxhdGUoKSAlPiUgbmV0d29ya19wbG90KG1pbl9jb3I9MC42KSArIGdndGl0bGUoIlNFIEJhYmllcyIpCmBgYAoKIyBYWSBTcGFjZSBEYXRhCldlJ2xsIGxvYWQgdGhlIGRhdGEgZnJvbSB0aGUgYGNoaWxkeHlkYXRhLmZlYXRoZXJgIGZpbGUgbWFkZSBpbiAwNnJhd3h5ZGF0YS5SbWQuIFNvIGFueSBuZXcgYmFiaWVzLCBwbGVhc2UgcnVuIHRoZSBmaXJzdCBjb2RlIGJsb2NrIGluIDA2IHRvIGluY2x1ZGUgaXQuIFRoZW4gd2UnbGwga2VlcCBhbGwgdGhlIGJhYmllcyB3ZSBhbHNvIGhhdmUgaW4gdGhlIEFPSSBkYXRhIGdyb3VwLiAKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmluY2x1ZGVkIDwtIGJhYmllcyAlPiUKICB1bmdyb3VwKCkgJT4lCiAgc2VsZWN0KG5hbWUpICU+JSAKICBkaXN0aW5jdCgpICU+JQogIHVubGlzdCgpCgp4eWRhdGEgPC0gcmVhZF9mZWF0aGVyKCIuLi9DaGlsZCBEYXRhL2NoaWxkeHlkYXRhLmZlYXRoZXIiKSAlPiUKICByZW5hbWUobmFtZSA9IHBhcnRpY2lwYW50KSAlPiUKICBmaWx0ZXIobmFtZSAlaW4lIGluY2x1ZGVkKQoKIyBHZXQgYWdlcwphZ2VzIDwtIHJlYWRfY3N2KCJjaGlsZHJlbmFnZXMuY3N2IikgJT4lCiAgcmVuYW1lKG5hbWUgPSBwYXJ0aWNpcGFudCkKeHlkYXRhIDwtIHh5ZGF0YSAlPiUgbGVmdF9qb2luKGFnZXMsIGJ5ID0gIm5hbWUiKSAlPiUKICBtdXRhdGUoYWdlID0gYWdlKjEyKSAlPiUKICBtdXRhdGUoYWdlZ3JvdXAgPSBjYXNlX3doZW4oCiAgICBhZ2UgPD0gOC45OSB+ICJ5b3VuZ2VyIiwKICAgIGFnZSA+PSA5LjAgJiBhZ2UgPCAxNSB+ICJvbGRlciIKICApKSAlPiUKICBtdXRhdGUobGFuZ3VhZ2UgPSBjYXNlX3doZW4oCiAgICBsYW5ndWFnZSA9PSAiRW5nbGlzaEV4cG9zZWQiIH4gIk5TRSIsCiAgICBsYW5ndWFnZSA9PSAiU2lnbkxhbmd1YWdlRXhwb3NlZCIgfiAiU0UiCiAgKSkgJT4lCiAgcmVuYW1lKGxhbmcgPSBsYW5ndWFnZSkgJT4lCiAgc2VsZWN0KG5hbWUsIGdyb3VwLCBnZW5kZXIsIGxhbmcsIGNvbmRpdGlvbiwgbWFyaywgdHJpYWwsIHJlcGV0aXRpb24sIHgsIHksIGFnZSwgYWdlZ3JvdXApICU+JQogIHNlcGFyYXRlKGNvbmRpdGlvbiwgaW50byA9IGMoInN0b3J5IiwgImNsaXAiLCAiZGlyZWN0aW9uIikpICU+JQogIHVuaXRlKCJzdG9yeSIsIGMoInN0b3J5IiwgImNsaXAiKSkgJT4lCiAgbXV0YXRlKGRpcmVjdGlvbiA9IGNhc2Vfd2hlbigKICAgIGRpcmVjdGlvbiA9PSAiRVIiIH4gInJldmVyc2VkIiwKICAgIGRpcmVjdGlvbiA9PSAiRlciIH4gImZvcndhcmQiCiAgKSkgJT4lCiAgbXV0YXRlKG5hbWUgPSBmYWN0b3IobmFtZSksCiAgICAgICAgIGdyb3VwID0gZmFjdG9yKGdyb3VwKSwKICAgICAgICAgZ2VuZGVyID0gZmFjdG9yKGdlbmRlciksCiAgICAgICAgIGxhbmcgPSBmYWN0b3IobGFuZyksCiAgICAgICAgIHN0b3J5ID0gZmFjdG9yKHN0b3J5KSwKICAgICAgICAgZGlyZWN0aW9uID0gZmFjdG9yKGRpcmVjdGlvbiksCiAgICAgICAgIG1hcmsgPSBmYWN0b3IobWFyayksCiAgICAgICAgIHRyaWFsID0gZmFjdG9yKHRyaWFsKSwKICAgICAgICAgcmVwZXRpdGlvbiA9IGZhY3RvcihyZXBldGl0aW9uKSwKICAgICAgICAgYWdlZ3JvdXAgPSBmYWN0b3IoYWdlZ3JvdXApKQpgYGAKCiMjIE92ZXJhbGwgTG9va2luZwpMZXQncyBjaGVjayB0aGF0IHdlIGhhdmUgbm8gc2lnbmlmaWNhbnQgZ3JvdXAgb3IgY29uZGl0aW9uIGRpZmZlcmVuY2VzIGluIHRlcm1zIG9mIHZhbGlkIChub3QgZW1wdHkpIGRhdGEgcG9pbnRzIGNvbGxlY3RlZC4gVGhpcyBpcyBzYW1lIGFzICJHbG9iYWwgTG9va2luZyIgd2UgaGF2ZSBhYm92ZSwgcmVhbGx5LCBidXQgdyByYXcgeHkgZGF0YS4gCgpgYGB7cn0KeHlfb3ZlcmFsbCA8LSB4eWRhdGEgJT4lCiAgZmlsdGVyKCFpcy5uYSh4KSkgJT4lCiAgZ3JvdXBfYnkobmFtZSwgYWdlLCBsYW5nLCBkaXJlY3Rpb24sIHN0b3J5LCByZXBldGl0aW9uKSAlPiUKICBzdW1tYXJpc2UoZGF0YV9wb2ludHMgPSBuKCkpICMgZ2V0cyB0b3RhbCBsb29raW5nIHBlcmNlbnQgZm9yIGVhY2ggdHJpYWwgZm9yIGVhY2ggYmFieQoKIyBUYWJsZSBvZiBtZWFucwp4eV9vdmVyYWxsICU+JSAKICBncm91cF9ieShuYW1lLCBsYW5nLCBkaXJlY3Rpb24pICU+JQogIHN1bW1hcmlzZShkYXRhX3BvaW50cyA9IG1lYW4oZGF0YV9wb2ludHMpKSAlPiUgIyBnZXQgYXZlcmFnZSBsb29raW5nIHBlcmNlbnQgZm9yIGVhY2ggYmFieQogIGdyb3VwX2J5KGxhbmcsIGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKG1lYW5fZGF0YV9wb2ludHMgPSBtZWFuKGRhdGFfcG9pbnRzKSwKICAgICAgICAgICAgY291bnQgPSBuKCksCiAgICAgICAgICAgIHNkID0gc2QoZGF0YV9wb2ludHMpLAogICAgICAgICAgICBzZSA9IHNkL3NxcnQoY291bnQpKSAlPiUKICBzZWxlY3QoLXNkKSAlPiUKICBwcmludCgpCgpnZ3Bsb3QoeHlfb3ZlcmFsbCwgYWVzKHggPSBhZ2UsIHkgPSBkYXRhX3BvaW50cywgY29sb3IgPSBkaXJlY3Rpb24sIGZpbGwgPSBkaXJlY3Rpb24pKSArIAogIGdlb21faml0dGVyKGFscGhhID0gMC41KSArCiAgZmFjZXRfZ3JpZCguIH4gbGFuZykgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UpICsKICBnZ3RpdGxlKCJEYXRhIFBvaW50cyIpICsKICB4bGFiKCJhZ2UgKG1vbnRocykiKSArCiAgeWxhYigiZGF0YSBwb2ludHMgcmVjb3JkZWQiKSArIAogIHRoZW1lX2J3KCkgCmBgYAoKCkEgbGluZWFyIG1vZGVsIHNob3dzIHRoZXJlIHdlcmUgbm8gc2lnbmlmaWNhbnQgZWZmZWN0cyBvZiBhbnkgZmFjdG9ycy4gV2UgY2FuIGNvbmNsdWRlIHRoZXJlIHdhcyBubyBlZmZlY3Qgb24gaG93ICptdWNoKiBkYXRhIHdhcyBjb2xsZWN0ZWQgZnJvbSB0aGUgYmFiaWVzLiAgIAoKYGBge3J9Cm92ZXJhbGxfeHlfbG0gPC0gbG1lcihkYXRhX3BvaW50cyB+IGFnZSArIGxhbmcgKiBkaXJlY3Rpb24gKyAoZGlyZWN0aW9ufG5hbWUpICsgKGRpcmVjdGlvbnxzdG9yeSksIGRhdGEgPSB4eV9vdmVyYWxsKQpzdW1tYXJ5KG92ZXJhbGxfeHlfbG0pIAojZ2djb2VmKG92ZXJhbGxfeHlfbG0pCmBgYAoKIyMgWFkgRGF0YSBMTU1zCk5vdyB3ZSdyZSBnb2luZyB0byBydW4gTE1NcyBvbiBiYWJpZXMnIHJhdzogCgoqIGhvcml6b250YWwgc3ByZWFkIChtaWRkbGUgNTAlIG9mIHggZGF0YTsgeElRUikKKiB2ZXJ0aWNhbCBzcHJlYWQgKG1pZGRsZSA1MCUgb2YgeSBkYXRhOyB5SVFSKQoqIHZpZXdpbmcgYXJlYSAoQSA9IG1pZGRsZS14ICogbWlkZGxlLXk7IGFyZWEpCgpCdXQgdG8gZG8gdGhpcyB3ZSBmaXJzdCB0cmltIGVhY2ggYmFieSdzIGRhdGEsIGdldHRpbmcgcmlkIG9mIHRoZSBmaXJzdCA2MCBzYW1wbGVzICgwLjUgc2Vjcykgb2YgZWFjaCB0cmlhbC4gCgpgYGB7cn0KeHlkYXRhIDwtIHh5ZGF0YSAlPiUKICBncm91cF9ieShuYW1lLHRyaWFsKSAlPiUKICBzbGljZSg2MDpuKCkpCgppcXIgPC0geHlkYXRhICU+JQogIGdyb3VwX2J5KG5hbWUsIGFnZSwgbGFuZywgc3RvcnksIGRpcmVjdGlvbiwgdHJpYWwpICU+JQogIHN1bW1hcmlzZSh4SVFSID0gSVFSKHgsbmEucm09VFJVRSksCiAgICAgICAgICAgICAgICAgICB5SVFSID0gSVFSKHksbmEucm09VFJVRSksCiAgICAgICAgICAgICAgICAgICB4bWVkID0gbWVkaWFuKHgsIG5hLnJtPVRSVUUpLAogICAgICAgICAgICAgICAgICAgeW1lZCA9IG1lZGlhbih5LCBuYS5ybT1UUlVFKSwKICAgICAgICAgICAgICAgICAgIGFyZWEgPSB4SVFSKnlJUVIpCmhlYWQoaXFyLDIwKQoKYGBgCgoKIyMjIE1pZGRsZSBYCgpSZXN1bHRzIHRlbGwgdXMgdGhhdCB0aGVyZSBpcyBhIHNpZ25pZmljYW50IGVmZmVjdCBvZiBhZ2Ugd2hlcmUgaG9yaXpvbnRhbCBzcHJlYWQgZ3JldyBuYXJyb3dlciB3aXRoIG9sZGVyIGJhYmllcyAocCA9IDAuMDI0OyBzbG9wZSA9IC0yLjIgcHgvbW9udGgpLiBUaGVyZSB3YXMgYSBtYXJnaW5hbCBlZmZlY3Qgb2YgbGFuZ3VhZ2Ugd2hlcmUgU0UgYmFiaWVzIGhhdmUgc2xpZ2h0bHkgbmFycm93ZXIgaG9yaXpvbnRhbCBzcHJlYWQgKDExIHB4OyBwID0gMC4wODgpLiBObyBlZmZlY3RzIG9mIHJldmVyc2FsIG9yIGludGVyYWN0aW9ucy4KCmBgYHtyfQp4aXFyX21lYW4gPC0gaXFyICU+JSAKICBncm91cF9ieShsYW5nLCBkaXJlY3Rpb24sIG5hbWUpICU+JQogIHN1bW1hcmlzZSh4SVFSID0gbWVhbih4SVFSLCBuYS5ybSA9IFQpKSAlPiUgIyBnZXRzIGF2ZXJhZ2UgbG9va2luZyBwZXJjZW50IGZvciBlYWNoIGJhYnkKICBncm91cF9ieShsYW5nLCBkaXJlY3Rpb24pICU+JQogIHN1bW1hcmlzZShtZWFuX3hJUVIgPSBtZWFuKHhJUVIpLCAjIGdldHMgZ3JvdXAgYXZlcmFnZXMKICAgICAgICAgICAgY291bnQgPSBuKCksCiAgICAgICAgICAgIHNkID0gc2QoeElRUiksCiAgICAgICAgICAgIHNlID0gc2Qvc3FydChjb3VudCkpICU+JQogIHNlbGVjdCgtc2QpICU+JQogIHByaW50KCkKCiMgUGxvdApnZ3Bsb3QoaXFyLCBhZXMoeCA9IGFnZSwgeSA9IHhJUVIsIGNvbG9yID0gZGlyZWN0aW9uLCBmaWxsID0gZGlyZWN0aW9uKSkgKyAKICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuNSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGZhY2V0X2dyaWQoLiB+IGxhbmcpICsKICBnZ3RpdGxlKCJIb3Jpem9udGFsIFNwcmVhZCIpICsKICB4bGFiKCIiKSArCiAgeWxhYigieElRUiIpCgpnZ3Bsb3QoeGlxcl9tZWFuLCBhZXMoeCA9IGxhbmcsIHkgPSBtZWFuX3hJUVIsIGZpbGwgPSBkaXJlY3Rpb24pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoKSkgKyAKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gbWVhbl94SVFSLXNlLCB5bWF4ID0gbWVhbl94SVFSK3NlKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLCB3aWR0aCA9IDAuMikgKwogIHRoZW1lX2xpbmVkcmF3KCkKCnhpcXJfbG0gPC0gbG1lcih4SVFSIH4gYWdlICsgbGFuZyAqIGRpcmVjdGlvbiArICgxfG5hbWUpICsgKDF8c3RvcnkpLCBkYXRhID0gaXFyKQpzdW1tYXJ5KHhpcXJfbG0pCiNnZ2NvZWYoeGlxcl9sbSkKYGBgCgoKIyMjIE1pZGRsZSBZCgpXZSBoYWQgYSBzaWduaWZpY2FudCBlZmZlY3Qgb2YgYWdlIHdoZXJlIHZlcnRpY2FsIHNwcmVhZCBnb3QgbmFycm93ZXIgd2l0aCBvbGRlciBiYWJpZXMgKHAgPSAwLjAxOSwgc2xvcGUgPSAtNS41IHB4L21vbnRoKS4gVGhlcmUgd2VyZSBubyBlZmZlY3Qgb2YgbGFuZ3VhZ2UsIGRpcmVjdGlvbiwgb3IgaW50ZXJhY3Rpb25zLiAKCmBgYHtyfQp5aXFyX21lYW4gPC0gaXFyICU+JSAKICBncm91cF9ieShsYW5nLCBkaXJlY3Rpb24sIG5hbWUpICU+JQogIHN1bW1hcmlzZSh5SVFSID0gbWVhbih5SVFSLCBuYS5ybSA9IFQpKSAlPiUgIyBnZXRzIGF2ZXJhZ2UgbG9va2luZyBwZXJjZW50IGZvciBlYWNoIGJhYnkKICBncm91cF9ieShsYW5nLCBkaXJlY3Rpb24pICU+JQogIHN1bW1hcmlzZShtZWFuX3lJUVIgPSBtZWFuKHlJUVIpLCAjIGdldHMgZ3JvdXAgYXZlcmFnZXMKICAgICAgICAgICAgY291bnQgPSBuKCksCiAgICAgICAgICAgIHNkID0gc2QoeUlRUiksCiAgICAgICAgICAgIHNlID0gc2Qvc3FydChjb3VudCkpICU+JQogIHNlbGVjdCgtc2QpICU+JQogIHByaW50KCkKCiMgUGxvdApnZ3Bsb3QoaXFyLCBhZXMoeCA9IGFnZSwgeSA9IHlJUVIsIGNvbG9yID0gZGlyZWN0aW9uLCBmaWxsID0gZGlyZWN0aW9uKSkgKyAKICBnZW9tX2ppdHRlcihhbHBoYSA9IDAuNSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFKSArCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGZhY2V0X2dyaWQoLiB+IGxhbmcpICsKICBnZ3RpdGxlKCJWZXJ0aWNhbCBTcHJlYWQiKSArCiAgeGxhYigiIikgKwogIHlsYWIoInlJUVIiKQoKZ2dwbG90KHlpcXJfbWVhbiwgYWVzKHggPSBsYW5nLCB5ID0gbWVhbl95SVFSLCBmaWxsID0gZGlyZWN0aW9uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsgCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IG1lYW5feUlRUi1zZSwgeW1heCA9IG1lYW5feUlRUitzZSksIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC45KSwgd2lkdGggPSAwLjIpICsKICB0aGVtZV9saW5lZHJhdygpCgp5aXFyX2xtIDwtIGxtZXIoeUlRUiB+IGFnZSArIGxhbmcgKiBkaXJlY3Rpb24gKyAoMXxuYW1lKSArICgxfHN0b3J5KSwgZGF0YSA9IGlxcikKc3VtbWFyeSh5aXFyX2xtKQojZ2djb2VmKHlpcXJfbG0pCmBgYAoKIyMjIFZpZXdpbmcgQXJlYQpBZ2FpbiwgYWdlIGlzIHNpZ25pZmljYW50IChwID0gMC4wMSkgc3VjaCB0aGF0IGFyZWEgZ2V0cyBzbWFsbGVyIHdpdGggYWdlIChhYm91dCA1MDAgc3EuIHB4LiBwZXIgbW9udGgpLiBObyBlZmZlY3Qgb2YgbGFuZ3VhZ2Ugb3IgZGlyZWN0aW9uIG9yIGludGVyYWN0aW9ucy4gCgpgYGB7cn0KYXJlYV9tZWFuIDwtIGlxciAlPiUgCiAgZ3JvdXBfYnkobGFuZywgZGlyZWN0aW9uLCBuYW1lKSAlPiUKICBzdW1tYXJpc2UoYXJlYSA9IG1lYW4oYXJlYSwgbmEucm0gPSBUKSkgJT4lICMgZ2V0cyBhdmVyYWdlIGxvb2tpbmcgcGVyY2VudCBmb3IgZWFjaCBiYWJ5CiAgZ3JvdXBfYnkobGFuZywgZGlyZWN0aW9uKSAlPiUKICBzdW1tYXJpc2UoYXJlYV9tZWFuID0gbWVhbihhcmVhKSwgIyBnZXRzIGdyb3VwIGF2ZXJhZ2VzCiAgICAgICAgICAgIGNvdW50ID0gbigpLAogICAgICAgICAgICBzZCA9IHNkKGFyZWEpLAogICAgICAgICAgICBzZSA9IHNkL3NxcnQoY291bnQpKSAlPiUKICBzZWxlY3QoLXNkKSAlPiUKICBwcmludCgpCgojIFBsb3QKZ2dwbG90KGlxciwgYWVzKHggPSBhZ2UsIHkgPSBhcmVhLCBjb2xvciA9IGRpcmVjdGlvbiwgZmlsbCA9IGRpcmVjdGlvbikpICsgCiAgZ2VvbV9qaXR0ZXIoYWxwaGEgPSAwLjUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSkgKwogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCkpICsKICBmYWNldF9ncmlkKC4gfiBsYW5nKSArCiAgZ2d0aXRsZSgiVmlld2luZyBBcmVhIikgKwogIHhsYWIoIiIpICsKICB5bGFiKCJBcmVhIChweF4yKSIpCgpnZ3Bsb3QoYXJlYV9tZWFuLCBhZXMoeCA9IGxhbmcsIHkgPSBhcmVhX21lYW4sIGZpbGwgPSBkaXJlY3Rpb24pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoKSkgKyAKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gYXJlYV9tZWFuLXNlLCB5bWF4ID0gYXJlYV9tZWFuK3NlKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjkpLCB3aWR0aCA9IDAuMikgKwogIHRoZW1lX2xpbmVkcmF3KCkKCmFyZWFfbG0gPC0gbG1lcihhcmVhIH4gYWdlICsgbGFuZyAqIGRpcmVjdGlvbiArICgxfG5hbWUpICsgKDF8c3RvcnkpLCBkYXRhID0gaXFyKQpzdW1tYXJ5KGFyZWFfbG0pCiNnZ2NvZWYoYXJlYV9sbSkKYGBgCgojIyBQbG90dGluZyBWaWV3aW5nIEFyZWEgCgpgYGB7cn0KbWVkaWFucyA8LSBpcXIgJT4lCiAgZ3JvdXBfYnkobmFtZSxsYW5nLGRpcmVjdGlvbikgJT4lCiAgc3VtbWFyaXNlKHhJUVIgPSBtZWRpYW4oeElRUixuYS5ybT1UUlVFKSwKICAgICAgICAgICAgICAgICAgIHlJUVIgPSBtZWRpYW4oeUlRUixuYS5ybT1UUlVFKSwKICAgICAgICAgICAgICAgICAgIHhtZWQgPSBtZWRpYW4oeG1lZCxuYS5ybT1UUlVFKSwKICAgICAgICAgICAgICAgICAgIHltZWQgPSBtZWRpYW4oeW1lZCxuYS5ybT1UUlVFKSkgJT4lCiAgZ3JvdXBfYnkobGFuZyxkaXJlY3Rpb24pICU+JSAKICBzdW1tYXJpc2UoeElRUiA9IG1lYW4oeElRUixuYS5ybT1UUlVFKSwKICAgICAgICAgICAgICAgICAgIHlJUVIgPSBtZWFuKHlJUVIsbmEucm09VFJVRSksCiAgICAgICAgICAgICAgICAgICB4ID0gbWVkaWFuKHhtZWQsbmEucm09VFJVRSksCiAgICAgICAgICAgICAgICAgICB5ID0gbWVkaWFuKHltZWQsbmEucm09VFJVRSkpICU+JQogIG11dGF0ZSh5ID0geSotMSwKICAgICAgICAgeG1pbiA9IHgtKHhJUVIvMiksCiAgICAgICAgIHhtYXggPSB4Kyh4SVFSLzIpLAogICAgICAgICB5bWluID0geS0oeUlRUi8yKSwKICAgICAgICAgeW1heCA9IHkrKHlJUVIvMikpCmltZyA8LSBwbmc6OnJlYWRQTkcoImNpbmR5LnBuZyIpCmcgPC0gZ3JpZDo6cmFzdGVyR3JvYihpbWcsIGludGVycG9sYXRlPVRSVUUsIHdpZHRoPXVuaXQoMSwibnBjIiksIGhlaWdodD11bml0KDEsIm5wYyIpKSAKZ2dwbG90KG1lZGlhbnMsIGFlcyhmaWxsPWRpcmVjdGlvbixjb2xvcj1kaXJlY3Rpb24pKSArCiAgYW5ub3RhdGlvbl9jdXN0b20oZywgeG1pbj0tSW5mLCB4bWF4PUluZiwgeW1pbj0tSW5mLCB5bWF4PUluZikgKwogIGdlb21fcmVjdChhZXMoeG1pbj14bWluLHltaW49eW1pbix4bWF4PXhtYXgseW1heD15bWF4KSxhbHBoYT0uMSkgKyAKICB0aGVtZV9saW5lZHJhdygpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLDEwODApLCBleHBhbmQgPSBjKDAsIDApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoLTcyMCwwKSwgZXhwYW5kID0gYygwLCAwKSkgKwogIGZhY2V0X3dyYXAoImxhbmciKQpgYGAKCiMgUHVwcGllcwpHZXQgcHVwcHkgZGF0YSEKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgcHVwcGllczEgPC0gcmVhZF90c3YoIi4uL0NoaWxkIERhdGEvX3B1cHBpZXMvYWxsIHB1cHBpZXMgZ3JvdXAgMSBzdW1zLnR4dCIsIG5hID0gIi0iKSAlPiUgCiMgICBjbGVhbl9uYW1lcygpICU+JQojICAgc2VsZWN0KC1jKGFnZSwgYW5hbHlzaXMsIGNoZWNrX2lmX3dhbnRfc2NhdHRlcnBsb3QsIGdlbmRlciwgbGFuZ3VhZ2UpKSAlPiUKIyAgIHJlbmFtZShuYW1lID0geDEpICU+JQojICAgbXV0YXRlKG1lYW4gPSByb3dNZWFucyguWzI6MTBdLCBuYS5ybSA9IFQpKSAlPiUKIyAgIHNlbGVjdChuYW1lLCBtZWFuKQojICAgCiMgcHVwcGllczIgPC0gcmVhZF90c3YoIi4uL0NoaWxkIERhdGEvX3B1cHBpZXMvYWxsIHB1cHBpZXMgZ3JvdXAgMiBzdW1zLnR4dCIsIG5hID0gIi0iKSAlPiUgCiMgICBjbGVhbl9uYW1lcygpICU+JQojICAgc2VsZWN0KC1jKGFnZSwgYW5hbHlzaXMsIGNoZWNrX2lmX3dhbnRfc2NhdHRlcnBsb3QsIGdlbmRlciwgbGFuZ3VhZ2UpKSAlPiUKIyAgIHJlbmFtZShuYW1lID0geDEpICU+JQojICAgbXV0YXRlKG1lYW4gPSByb3dNZWFucyguWzI6MTddLCBuYS5ybSA9IFQpKSAlPiUKIyAgIHNlbGVjdChuYW1lLCBtZWFuKQojIAojIHB1cHBpZXMgPC0gcmJpbmQocHVwcGllczEsIHB1cHBpZXMyKQojIAojIHBhcnRpY2lwYW50cyA8LSB4eWRhdGEgJT4lIAojICAgc2VsZWN0KG5hbWUsIGdyb3VwLCBnZW5kZXIsIGxhbmcpICU+JSAKIyAgIGRpc3RpbmN0KCkKIyAKIyBwdXBwaWVzIDwtIGxlZnRfam9pbihwYXJ0aWNpcGFudHMsIHB1cHBpZXMsIGJ5ID0gIm5hbWUiKQojIAojIHN1bW1hcnkobG0oZGF0YSA9IHB1cHBpZXMsIG1lYW4gfiBsYW5nKSkKIyAKIyBwdXBwaWVzX3NlIDwtIGZpbHRlcihwdXBwaWVzLCBsYW5nID09ICJOU0UiKQojIHB1cHBpZXNfbnNlIDwtIGZpbHRlcihwdXBwaWVzLCBsYW5nID09ICJTRSIpCiMgCiMgdC50ZXN0KHB1cHBpZXNfc2UkbWVhbiwgcHVwcGllc19uc2UkbWVhbikKCiMgTGV0J3MgZG8gdGhpcyBhZ2FpbiBidXQgcHJlc2VydmUgcHVwcHktbGV2ZWwgZGF0YQpwdXBwaWVzMSA8LSByZWFkX3RzdigiLi4vQ2hpbGQgRGF0YS9fcHVwcGllcy9hbGwgcHVwcGllcyBncm91cCAxIHN1bXMudHh0IiwgbmEgPSAiLSIpICU+JSAKICBjbGVhbl9uYW1lcygpICU+JQogIHNlbGVjdCgtYyhhZ2UsIGFuYWx5c2lzLCBjaGVja19pZl93YW50X3NjYXR0ZXJwbG90LCBnZW5kZXIsIGxhbmd1YWdlKSkgJT4lCiAgcmVuYW1lKG5hbWUgPSB4MSkgJT4lCiAgZ2F0aGVyKGtleSA9IHB1cHB5LCB2YWx1ZSA9IHNlYywgLW5hbWUpICU+JQogIG11dGF0ZShwdXBzID0gY2FzZV93aGVuKAogICAgc3RyX2RldGVjdChwdXBweSwgImh1c2tpZXMiKSB+ICJodXNraWVzIiwKICAgIHN0cl9kZXRlY3QocHVwcHksICJnb2xkZW4iKSB+ICJnb2xkZW4iLAogICAgc3RyX2RldGVjdChwdXBweSwgIndhd2EiKSB+ICJ3YXdhIiwKICAgIHN0cl9kZXRlY3QocHVwcHksICJmcmlzYnkiKSB+ICJmcmlzYnkiLAogICAgc3RyX2RldGVjdChwdXBweSwgImJ1bGxkb2ciKSB+ICJidWxsZG9nIiwKICAgIHN0cl9kZXRlY3QocHVwcHksICJwdXBweV9qcGciKSB+ICJwdXBweSIsCiAgICBUUlVFIH4gcHVwcHkKICApKQoKcHVwcGllczIgPC0gcmVhZF90c3YoIi4uL0NoaWxkIERhdGEvX3B1cHBpZXMvYWxsIHB1cHBpZXMgZ3JvdXAgMiBzdW1zLnR4dCIsIG5hID0gIi0iKSAlPiUgCiAgY2xlYW5fbmFtZXMoKSAlPiUKICBzZWxlY3QoLWMoYWdlLCBhbmFseXNpcywgY2hlY2tfaWZfd2FudF9zY2F0dGVycGxvdCwgZ2VuZGVyLCBsYW5ndWFnZSkpICU+JQogIHJlbmFtZShuYW1lID0geDEpICU+JQogIGdhdGhlcihrZXkgPSBwdXBweSwgdmFsdWUgPSBzZWMsIC1uYW1lKSAlPiUKICBtdXRhdGUocHVwcyA9IGNhc2Vfd2hlbigKICAgIHN0cl9kZXRlY3QocHVwcHksICJodXNraWVzIikgfiAiaHVza2llcyIsCiAgICBzdHJfZGV0ZWN0KHB1cHB5LCAiZ29sZGVuIikgfiAiZ29sZGVuIiwKICAgIHN0cl9kZXRlY3QocHVwcHksICJ3YXdhIikgfiAid2F3YSIsCiAgICBzdHJfZGV0ZWN0KHB1cHB5LCAiZnJpc2J5IikgfiAiZnJpc2J5IiwKICAgIHN0cl9kZXRlY3QocHVwcHksICJidWxsZG9nIikgfiAiYnVsbGRvZyIsCiAgICBzdHJfZGV0ZWN0KHB1cHB5LCAicHVwcGllcyIpIH4gInB1cHBpZXMiLAogICAgVFJVRSB+IHB1cHB5CiAgKSkKCnB1cHBpZXMgPC0gcmJpbmQocHVwcGllczEscHVwcGllczIpCgpwYXJ0aWNpcGFudHMgPC0geHlkYXRhICU+JQogIHNlbGVjdChuYW1lLCBncm91cCwgZ2VuZGVyLCBsYW5nKSAlPiUKICBkaXN0aW5jdCgpCgpwdXBwaWVzIDwtIGxlZnRfam9pbihwYXJ0aWNpcGFudHMsIHB1cHBpZXMsIGJ5ID0gIm5hbWUiKQoKc3VtbWFyeShsbWVyKGRhdGEgPSBwdXBwaWVzLCBzZWMgfiBsYW5nICsgKDF8bmFtZSkgKyAoMXxwdXBzKSkpCgpnZ3Bsb3QocHVwcGllcywgYWVzKHggPSBsYW5nLCB5ID0gc2VjLCBmaWxsID0gbGFuZykpICsgZ2VvbV9ib3hwbG90KCkKYGBgCgo=